有的搜索引擎排名与网站的加载速度或多或少有些关系,而这次百度闪电算法来了,将网站首屏打开速度被列入优化排名行列,并明确指定打开时间为2秒,那么我们在如何做好网页首屏的打开速度呢?
要做好网站速度优化,就必须要做好软件和硬件两个方面,从网站程序以及页面设计本身解决网页资源的加载,然后就是服务器本身需要有足够的带宽及处理资源,下面子凡就依次来与大家探讨。
首先我们打开一个网页看到的都只是前端,所以我们看到一个页面背后的支持就是HTML代码,其中就包含了各种网页标签,其中包括网站优化中的TKD,载入的渲染资源:javascript、css,已经页面内容:图片、音频、视频等。
一、代码的足够简洁
减少代码冗余,保持简洁的代码风格,这是作为一个网页程序员的必修,能同样实现一个效果的能用css就尽量不用js,能用两行代码解决问题的就别写三行,这是最基础的一点。
二、减少资源载入
这里子凡所说的资源主要是指js、css文件,因为我知道现在很多的前端开发设计人员喜欢用各种开源的特效或者别人做好的效果,其中包括为了给网站添加几个图标就引入一个开源的图标字体库,为了某个特效又在引入几个js和css文件,这无形之中就为网站加重了“份量”。
三、图片使用懒加载,视频或音频禁止自动播放
还记得子凡曾在泪雪博客写过关于“图片懒加载是否会影响网站SEO优化”的文章,其中就说到过如何合理的使用图片懒加载技术提升用户体验而不影响网站优化,因为懒加载是为了防止页面一被打开就立即载入图片,这样就会占用网络带宽,从而影响网站的打开速度以及网站首屏的请求,所以非正文图片都是可以做懒加载的。
图片是每个网站基本都少不了的东西,但是对于做视频、音频的站点来说,如果打开页面就自动播放,占用的网站带宽资源都更多了,所以这也是一个网站打开速度优化的一个小知识。
四、使用CDN加速静态资源
关于使用CDN加速是否影响网站优化的文章子凡也曾有过讨论,子凡对于网站整体做CDN加速还是有些不太认同,但是对于将网站静态资源做CDN加速镜像或者缓存优化却是非常认同的,例如将网站的js、css、图片等文件做CDN加速是更有利于整个网站的加载和打开速度的。
五、提升页面渲染速度
将CSS样式写在头部样式表中,减少由CSS文件网络请求造成的渲染阻塞。
将JavaScript放到文档末尾,或使用async方式加载,避免JS执行阻塞渲染。
对非文字元素(如图片,视频)指定宽高,避免浏览器重排重绘。
六、服务器本身的速度优化
启用服务器Gzip压缩功能;
开启数据库查询及页面缓存功能(如果是直接生成静态页面的网站可忽略);
升级或者保证服务器足够的网络带宽;
开启网站缓存,充分利用本地缓存。
同样随着网络安全的重视程度,如果你的网站已经安装SSL证书启用了HTTPS协议,那么你可以开启HTTPS/2或者SPDY这个功能,可以在某些程度上加速网站的打开。
总结
虽然百度“闪电算法”是正对移动搜索排名的算法,而子凡上述的所有知识点都是通用的,并没有移动端或电脑端的区分,写得不算非常详细,子凡只是将这些非常容易出现的问题或者被忽略的问题按照自己的思路写出来了,虽然语句都写得非常简单,但是要真的操作起来,如果你不懂网页代码或者服务器,操作起来可能也会是已经非常困难的事情。
最后最后子凡还想给自己的 Fanly MIP 主题打个广告,如果你使用WordPress程序,并且重视百度这次的闪电算法,你可以使用子凡开发的这个MIP主题和插件,因为主题和插件都提供免费版本,所以大家可以非常方便的接入,当然你也可以支持子凡或者想要更好的服务可以购买我的收费版本。
好啦,如果你看这里,本文从标题到正文,再到最后的广告你都已经阅读完毕。see you。。。
除非注明,否则均为泪雪博客原创文章,转载请以链接形式标明本文地址
本文链接:https://zhangzifan.com/website-speed-seo.html
QFile read("./music/Nevada.mp3");
if (!read.open(QIODevice::ReadOnly))
{
qDebug() << "文件打开失败,请重试~";
}
//下面用的对象,必须动态申请,不然构造函数执行完毕,局部变量内存会被释放
QByteArray *data=new QByteArray(read.readAll());
read.close();
QBuffer *buffer=new QBuffer(data,this);
if (!buffer->open(QIODevice::ReadWrite))
{
qDebug() << "buffer error";
}
//qDebug() << data;
QMediaPlayer *player=new QMediaPlayer(this);
player->setMedia(QMediaContent(),buffer);
player->play();
QMediaPlayer *player=new QMediaPlayer(this);
player->setMedia(QUrl("./music/MMD.mp4"));
player->play();
?
QVideoWidget* videowidget=new QVideoWidget(this);
player->setVideoOutput(videowidget);
vs中如果提示编译器堆空间不足,则打开vcxproj工程文件,在PropertyGroup中添加如下代码
<PropertyGroup Label="Globals">
<!-- 资源文件加载,防止编译器堆空间不足 -->
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
【领QT开发教程学习资料,点击下方链接免费领取↓↓,先码住不迷路~】
点击→领取「链接」
在Qt中,要想使计算机发出响声,最简单的方法是调用QApplication : : beep()静态函数。而Qt Multimedia模块中提供了多个类来实现不同层次的音频输入,输出和处理。
QSound类提供了播放.wav声音文件的方法。
Qt 提供了 GUI 应用程序中最常用的音频操作:异步播放声音文件。 使用静态 play() 函数最容易做到这一点:
QSound::play("mysounds/bells.wav");
或者,首先从声音文件创建一个 QSound 对象,然后调用 play() 槽:
QSound bells("mysounds/bells.wav");
bells.play();
在这两种情况下,文件可能是本地文件或资源中的文件。
一旦创建了 QSound 对象,就可以查询它的 fileName() 和 loops() 总数(即声音播放的次数)。 可以使用 setLoops() 函数更改重复次数。 播放声音时,loopsRemaining() 函数返回剩余的重复次数。 使用 isFinished() 函数来确定声音是否播放完毕。
使用 QSound 对象播放的声音可能会比静态 play() 函数使用更多的内存,但它也可能播放得更快(取决于底层平台的音频设施)。
如果您需要更好地控制播放声音,请考虑 QSoundEffect 或 QAudioOutput 类。
QSound(const QString &filename, QObject *parent=nullptr)
virtual ~QSound()
QString fileName() const
bool isFinished() const
int loops() const
int loopsRemaining() const
void setLoops(int number)
void play()
void stop()
void play(const QString &filename)
QSoundEffect类提供了一种播放低延迟声音效果的方法 。
这个类允许你以较低的延迟方式播放未压缩的音频文件(通常是WAV文件),并且适用于“反馈”类型的声音,以响应用户的动作(例如虚拟键盘声音,弹出对话框的正面或负面反馈,或游戏声音)。 如果低延迟不重要,可以考虑使用QMediaPlayer类,因为它支持更广泛的媒体格式,并且资源消耗更少。
看个例子:
QSoundEffect effect;
effect.setSource(QUrl::fromLocalFile("F:/MyCode/QtObjectCode/QtCourse/soundeffect/video_call.wav"));
effect.setLoopCount(QSoundEffect::Infinite);
effect.setVolume(0.8f);
effect.play();
通常应该重用音效,这样可以提前完成所有解析和准备工作,并且只在必要时触发。 这有助于降低延迟音频播放。
class MyGame
{
public:
MyGame(): m_videoCall(this)
{
m_videoCall.setSource(QUrl::fromLocalFile("video_call.wav"));
m_videoCall.setVolume(0.25f);
?
// Set up click handling etc.
connect(clickSource, &QPushButton::clicked, &m_videoCall, &QSoundEffect::play);
}
private:
QSoundEffect m_videoCall;
}
由于QSoundEffect需要更多的资源来实现较低的延迟播放,平台可能会限制同时播放声音效果的数量。
【领QT开发教程学习资料,点击下方链接免费领取↓↓,先码住不迷路~】
点击→领取「链接」
//设置源(wav文件路径)
void setSource(const QUrl &url)
//设置循环次数
void setLoopCount(int loopCount)
//设置静音
void setMuted(bool muted)
//设置音量0~1之间
void setVolume(qreal volume)
//音效是否加载完毕
bool isLoaded() const
//是否是静音
bool isMuted() const
//是否正在播放
bool isPlaying() const
void play() //播放
void stop() //停止
void categoryChanged()
void loadedChanged()
void loopCountChanged()
void loopsRemainingChanged()
void mutedChanged()
void playingChanged()
void sourceChanged()
void statusChanged()
void volumeChanged()
枚举 | 描述 |
QSoundEffect::Null | 未设置源或源为空。 |
QSoundEffect::Loading | SoundEffect 正在尝试加载源。 |
QSoundEffect::Ready | 源已加载并准备好播放。 |
QSoundEffect::Error | 运行过程中出现错误,例如加载源失败。 |
QMediaPlayer类是一个高级媒体播放类。 它可以用来播放歌曲、电影和网络广播等内容。 要播放的内容被指定为QMediaContent对象,可以将其视为附加了附加信息的主要或规范URL。 当提供QMediaContent时,可以开始播放。
QMediaPlayer player;
player.setMedia(QUrl::fromLocalFile("F:/MyCode/QtObjectCode/QtCourse/soundeffect/That-Girl.mp3"));
player.setVolume(50);
player.play();
QVideoWidget可以与QMediaPlayer一起用于视频渲染,QMediaPlaylist用于访问播放列表功能。
QVideoWidget wid;
wid.show();
?
QMediaPlaylist playList;
playList.addMedia(QUrl::fromLocalFile("F:/MyCode/QtObjectCode/QtCourse/soundeffect/That-Girl.mp3"));
playList.addMedia(QUrl::fromLocalFile("F:/MyCode/QtObjectCode/QtCourse/soundeffect/干坤坤.mp4"));
?
QMediaPlayer player;
player.setPlaylist(&playList);
//player.setMedia(QUrl::fromLocalFile("F:/MyCode/QtObjectCode/QtCourse/soundeffect/That-Girl.mp3"));
player.setVolume(50);
playList.next();
player.setVideoOutput(&wid);
player.play();
//该值是当前媒体的总播放时间,以毫秒为单位。 该值可能在QMediaPlayer对象的生命周期中发生变化,并且可能在初始回放开始时不可用,请连接到durationChanged()信号来接收状态通知。
qint64 duration() const
//将QVideoWidget视频输出附加到媒体播放器。
void setVideoOutput(QVideoWidget *output)
void setVideoOutput(QGraphicsVideoItem *output)
void setVideoOutput(QAbstractVideoSurface *surface)
//暂停播放当前源
void pause()
//开始或恢复播放当前源
void play()
//设置当前媒体源。 使用mediaStatusChanged()和error()信号,以便在加载媒体和加载过程中发生错误时得到通知
void setMedia(const QMediaContent &media, QIODevice *stream=nullptr)
//设置静音
void setMuted(bool muted)
//设置倍速播放
void setPlaybackRate(qreal rate)
//设置播放列表
void setPlaylist(QMediaPlaylist *playlist)
//设置播放位置,以媒体开始后的毫秒数为单位。 位置的周期性变化将用信号positionChanged()表示,更新间隔可以用QMediaObject的方法setNotifyInterval()设置。
void setPosition(qint64 position)
//此属性保存当前播放音量。 播放音量是线性缩放的,从0(静音)到100(全音量)。默认为100
void setVolume(int volume)
//停止播放,并将播放位置重置到开始
void stop()
//表示当前播放内容已更改为media。
void currentMediaChanged(const QMediaContent &media)
//表示内容的持续时间已更改为持续时间,以毫秒表示。
void durationChanged(qint64 duration)
//产生了错误
void error(QMediaPlayer::Error error)
//表示媒体来源已转变为media。
void mediaChanged(const QMediaContent &media)
//表示当前媒体的状态已经改变
void mediaStatusChanged(QMediaPlayer::MediaStatus status)
//静音状态改变
void mutedChanged(bool muted)
//播放速率改变
void playbackRateChanged(qreal rate)
//播放位置改变
void positionChanged(qint64 position)
//表示播放器对象的状态已经改变。
void stateChanged(QMediaPlayer::State state)
//音量改变
void volumeChanged(int volume)
(enum QMediaPlayer::Error)媒体播放器产生的具体错误。
枚举 | 描述 |
MediaPlayer::NoError | 没有错误发生 |
QMediaPlayer::ResourceError | 无法解析媒体源 |
QMediaPlayer::FormatError | 媒体资源的格式不受(完全)支持。 重新播放是可能的,但没有音频或视频组件。 |
QMediaPlayer::NetworkError | 网络错误 |
QMediaPlayer::AccessDeniedError | 没有播放媒体资源的适当权限。 |
QMediaPlayer::ServiceMissingError | 找不到有效的播放服务,无法继续播放。 |
(enum QMediaPlayer::Flag)播放标志。
枚举 | 描述 |
QMediaPlayer::LowLatency | 该播放器预计将用于简单的音频格式,播放没有明显的延迟。 这种回放服务可以用于蜂鸣声、铃声等。 |
QMediaPlayer::StreamPlayback | 该播放器预计将播放基于QIODevice的流。 如果传递给QMediaPlayer构造器,将选择支持流回放的服务。 |
QMediaPlayer::VideoSurface | 期望播放器能够呈现为QAbstractVideoSurface输出。 |
(enum QMediaPlayer::MediaStatus)定义媒体播放器当前媒体的状态。
枚举 | 描述 |
QMediaPlayer::UnknownMediaStatus | 无法确定媒体的状态。 |
QMediaPlayer::NoMedia | 没有当前的媒体。 播放器处于停止状态。 |
QMediaPlayer::LoadingMedia | 当前媒体正在加载中。 播放器可能处于任何状态。 |
QMediaPlayer::LoadedMedia | 已加载当前媒体。 播放器处于停止状态。 |
QMediaPlayer::StalledMedia | 由于缓冲不足或其他一些临时中断,当前媒体的播放已停止。 播放器处于PlayingState或PausedState |
QMediaPlayer::BufferingMedia | 播放器正在缓冲数据,但缓冲了足够的数据以供播放。 播放器处于PlayingState或PausedState。 |
QMediaPlayer::BufferedMedia | 播放器已经完全缓冲了当前的媒体。 播放器处于PlayingState或PausedState。 |
QMediaPlayer::EndOfMedia | 播放已经结束。 播放器处于停止状态。 |
QMediaPlayer::InvalidMedia | 当前媒体无法播放。 播放器处于停止状态。 |
(enum QMediaPlayer::State)媒体播放器的当前状态。
枚举 | 描述 |
QMediaPlayer::StoppedState | 播放停止状态 |
QMediaPlayer::PlayingState | 播放进行状态 |
QMediaPlayer::PausedState | 播放暂停状态 |
QMediaPlaylist类提供了要播放的媒体内容列表。
QMediaPlaylist旨在与其他媒体对象一起使用,如QMediaPlayer。
QMediaPlaylist允许访问服务固有的播放列表功能(如果可用的话),否则它提供本地内存播放列表实现。
playlist=new QMediaPlaylist;
playlist->addMedia(QUrl("http://example.com/movie1.mp4"));
playlist->addMedia(QUrl("http://example.com/movie2.mp4"));
playlist->addMedia(QUrl("http://example.com/movie3.mp4"));
playlist->setCurrentIndex(1);
?
player=new QMediaPlayer;
player->setPlaylist(playlist);
?
videoWidget=new QVideoWidget;
player->setVideoOutput(videoWidget);
videoWidget->show();
?
player->play();
根据播放列表源代码的实现,大多数播放列表更改操作可以是异步的。
【领QT开发教程学习资料,点击下方链接免费领取↓↓,先码住不迷路~】
点击→领取「链接」
QMediaPlaylist(QObject *parent=nullptr)
virtual ~QMediaPlaylist()
bool addMedia(const QMediaContent &content)
bool addMedia(const QList<QMediaContent> &items)
bool insertMedia(int pos, const QMediaContent &content)
bool insertMedia(int pos, const QList<QMediaContent> &items)
bool removeMedia(int pos)
bool removeMedia(int start, int end)
bool clear()
bool save(const QUrl &location, const char *format=nullptr)
bool save(QIODevice *device, const char *format)
void load(const QNetworkRequest &request, const char *format=nullptr)
void load(const QUrl &location, const char *format=nullptr)
void load(QIODevice *device, const char *format=nullptr)
int currentIndex() const
QMediaContent currentMedia() const
QMediaContent media(int index) const
int nextIndex(int steps=1) const
int previousIndex(int steps=1) const
int mediaCount() const
bool moveMedia(int from, int to)
void setPlaybackMode(QMediaPlaylist::PlaybackMode mode)
QMediaPlaylist::Error error() const
QString errorString() const
bool isEmpty() const
bool isReadOnly() const
void next()
void previous()
void setCurrentIndex(int playlistPosition)
void shuffle()
void currentIndexChanged(int position)
void currentMediaChanged(const QMediaContent &content)
void loadFailed()
void loaded()
void mediaAboutToBeInserted(int start, int end)
void mediaAboutToBeRemoved(int start, int end)
void mediaChanged(int start, int end)
void mediaInserted(int start, int end)
void mediaRemoved(int start, int end)
void playbackModeChanged(QMediaPlaylist::PlaybackMode mode)
(enum QMediaPlaylist::Error)QMediaPlaylist错误码。
枚举 | 描述 |
QMediaPlaylist::NoError | 没有错误 |
QMediaPlaylist::FormatError | 格式错误 |
QMediaPlaylist::FormatNotSupportedError | 格式不支持 |
QMediaPlaylist::NetworkError | 网络错误 |
QMediaPlaylist::AccessDeniedError | 访问错误(拒绝访问) |
(enum QMediaPlaylist::PlaybackMode)描述了播放列表中的播放顺序。
枚举 | 描述 |
QMediaPlaylist::CurrentItemOnce | 单曲播放一次 |
QMediaPlaylist::CurrentItemInLoop | 单曲循环 |
QMediaPlaylist::Sequential | 顺序播放(列表播放完结束) |
QMediaPlaylist::Loop | 列表循环(列表播放完,从头开始继续播放) |
QMediaPlaylist::Random | 随机播放 |
QMediaContent类提供对与媒体内容相关的资源的访问。
QMediaContent在多媒体框架内用作媒体内容的逻辑句柄。 一个QMediaContent对象包含一个QNetworkRequest,它提供了内容的URL。
非空QMediaContent将始终具有对通过request()方法可用的内容的引用。
另外,QMediaContent可以表示播放列表,并包含指向有效QMediaPlaylist对象的指针。 在这种情况下URL是可选的,可以是空的,也可以指向播放列表的URL。
QMediaContent(QMediaPlaylist *playlist, const QUrl &contentUrl=QUrl(), bool takeOwnership=false)
QMediaContent(const QMediaContent &other)
QMediaContent(const QNetworkRequest &request)
QMediaContent(const QUrl &url)
QMediaContent()
QMediaContent &operator=(const QMediaContent &other)
~QMediaContent()
bool isNull() const
QMediaPlaylist *playlist() const
QNetworkRequest request() const
bool operator!=(const QMediaContent &other) const
bool operator==(const QMediaContent &other) const
QMediaPlayer类可用来播放视频,只不过需要搭配专门的视频显示控件来使用。
void setVideoOutput(QVideoWidget *output)
void setVideoOutput(QGraphicsVideoItem *output)
//当前媒体的视频是否可用,如果可用,可以使用QVideoWidget类来查看视频。
bool isVideoAvailable() const
QVideoWidget类提供了一个小部件,用于呈现由媒体对象生成的视频。
将 QVideoWidget 附加到 QMediaObject 允许它显示该媒体对象的视频或图像输出。 QVideoWidget 通过在其构造函数中传递指向 QMediaObject 的指针附加到媒体对象,并通过销毁 QVideoWidget 来分离。
player=new QMediaPlayer;
?
playlist=new QMediaPlaylist(player);
playlist->addMedia(QUrl("http://example.com/myclip1.mp4"));
playlist->addMedia(QUrl("http://example.com/myclip2.mp4"));
?
videoWidget=new QVideoWidget;
player->setVideoOutput(videoWidget);
?
videoWidget->show();
playlist->setCurrentIndex(1);
player->play();
注意:一次只能将一个显示输出附加到媒体对象。
QVideoWidget(QWidget *parent=nullptr)
virtual ~QVideoWidget()
Qt::AspectRatioMode aspectRatioMode() const
int brightness() const //亮度
int contrast() const //对比度
int hue() const //色调
bool isFullScreen() const //是否全屏
int saturation() const //饱和度
//设置视频缩放时,宽度和高度的变化模式
void setAspectRatioMode(Qt::AspectRatioMode mode)
//调整显示视频的亮度。有效亮度值范围在 -100 到 100 之间,默认值为 0。
void setBrightness(int brightness)
//调整显示的视频的对比度。有效对比度值范围在-100到100之间,默认值为0。
void setContrast(int contrast)
//调整显示视频的色调。有效的色调值范围在 -100 到 100 之间,默认值为 0。
void setHue(int hue)
//调整显示视频的饱和度。 有效的饱和度值范围在-100到100之间,默认值是0。
void setSaturation(int saturation)
//设置窗口全屏显示
void setFullScreen(bool fullScreen)
//亮度改变
void brightnessChanged(int brightness)
//对比度改变
void contrastChanged(int contrast)
//是否全屏状态改变
void fullScreenChanged(bool fullScreen)
//饱和度改变
void saturationChanged(int saturation)
//色调改变
void hueChanged(int hue)
https://www.cnblogs.com/lxuechao/p/12677357.html
QCameraInfo 类提供有关相机设备的一般信息。
QCameraInfo 允许您查询系统上当前可用的相机设备。
静态函数 defaultCamera() 和 availableCameras() 为您提供所有可用相机的列表。
此示例打印所有可用相机的名称:
const QList<QCameraInfo> cameras=QCameraInfo::availableCameras();
for (const QCameraInfo &cameraInfo : cameras)
qDebug() << cameraInfo.deviceName();
一个QCameraInfo可以用来构造一个QCamera。 下面的例子实例化所有可用相机设备中第一个相机设备QCamera:
const QList<QCameraInfo> cameras=QCameraInfo::availableCameras();
camera=new QCamera(cameras.first());
你也可以使用QCameraInfo来获得一个相机设备的一般信息,例如描述,在系统上的物理位置,或相机传感器的方向。
QCamera myCamera;
QCameraInfo cameraInfo(myCamera);
?
if (cameraInfo.position()==QCamera::FrontFace)
qDebug() << "摄像头位于硬件系统的正面。";
else if (cameraInfo.position()==QCamera::BackFace)
qDebug() << "摄像头位于硬件系统的背面。";
?
qDebug() << "相机传感器方向是 " << cameraInfo.orientation() << " 度.";
QCamera类为系统摄像机设备提供接口。
QCamera可以与QCameraViewfinder一起使用,用于取景器显示,QMediaRecorder用于视频录制,QCameraImageCapture用于图像拍摄。
你可以使用QCameraInfo列出可用的相机并选择使用哪一个。
QCamera::CaptureModes captureMode() const
void setCaptureMode(QCamera::CaptureModes mode)
void setViewfinder(QVideoWidget *viewfinder)
void setViewfinder(QGraphicsVideoItem *viewfinder)
捕获模式
枚举 | 描述 |
QCamera::CaptureViewfinder | 取景器模式,只是简单的显示 |
QCamera::CaptureStillImage | 帧捕获模式,比如:拍照 |
QCamera::CaptureVideo | 视频捕获模式,比如:录制视频 |
者:Mino
原因:html代码下载到WebView后,webkit开始解析网页各个节点,发现有外部样式文件或者外部脚本文件时,会异步发起网络请求下载文件,但如果在这之前也有解析到image节点,那势必也会发起网络请求下载相应的图片。在网络情况较差的情况下,过多的网络请求就会造成带宽紧张,影响到css或js文件加载完成的时间,造成页面空白loading过久。
解决方法:告诉WebView先不要自动加载图片,等页面finish后再发起图片加载。
//设置是否开启密码保存功能,不建议开启,默认已经做了处理,存在盗取密码的危险
WebView.setSavePassword(false);
原因:4.0以上的系统我们开启硬件加速后,WebView渲染页面更加快速,拖动也更加顺滑。但有个副作用就是,当WebView视图被整体遮住一块,然后突然恢复时(比如使用SlideMenu将WebView从侧边滑出来时),这个过渡期会出现白块同时界面闪烁。
解决方法:是在过渡期前将WebView的硬件加速临时关闭,过渡期后再开启。
/**
* 请求网络出现error
* @param view view
* @param errorCode 错误
* @param description description
* @param failingUrl 失败链接
*/
@Override
public void onReceivedError(WebView view, int errorCode, String description, String
failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
if (errorCode==404) {
//用javascript隐藏系统定义的404页面信息
String data="Page NO FOUND!";
view.loadUrl("javascript:document.body.innerHTML=\"" + data + "\"");
} else {
if (webListener!=null){
webListener.showErrorView();
}
}
}
// 向主机应用程序报告Web资源加载错误。这些错误通常表明无法连接到服务器。
// 值得注意的是,不同的是过时的版本的回调,新的版本将被称为任何资源(iframe,图像等)
// 不仅为主页。因此,建议在回调过程中执行最低要求的工作。
// 6.0 之后
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.M) {
X5WebUtils.log("服务器异常"+error.getDescription().toString());
}
//ToastUtils.showToast("服务器异常6.0之后");
//当加载错误时,就让它加载本地错误网页文件
//mWebView.loadUrl("file:///android_asset/errorpage/error.html");
if (webListener!=null){
webListener.showErrorView();
}
}
/**
* 这个方法主要是监听标题变化操作的
* @param view view
* @param title 标题
*/
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
if (title.contains("404") || title.contains("网页无法打开")){
if (webListener!=null){
webListener.showErrorView();
}
} else {
// 设置title
}
}
原因:WebView.loadUrl("url") 不会立马就回调 onPageStarted 或者 onProgressChanged 因为在这一时间段,WebView 有可能在初始化内核,也有可能在与服务器建立连接,这个时间段容易出现白屏,白屏用户体验是很糟糕的。
解决方法:提前显示进度条虽然不是提升性能 , 但是对用户体验来说也是很重要的一点。
/**
* 在加载资源时通知主机应用程序发生SSL错误
* 作用:处理https请求
* @param view view
* @param handler handler
* @param error error
*/
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
super.onReceivedSslError(view, handler, error);
if (error!=null){
String url=error.getUrl();
}
//https忽略证书问题
if (handler!=null){
//表示等待证书响应
handler.proceed();
// handler.cancel(); //表示挂起连接,为默认方式
// handler.handleMessage(null); //可做其他处理
}
}
原因:WebView 默认开启密码保存功能 mWebView.setSavePassword(true),如果该功能未关闭,在用户输入密码时,会弹出提示框,询问用户是否保存密码,如果选择”是”,密码会被明文保到 /data/data/com.package.name/databases/webview.db 中,这样就有被盗取密码的危险。
解决方法:通过 WebSettings.setSavePassword(false) 关闭密码保存提醒功能。
@Override
protected void onDestroy() {
try {
//有音频播放的web页面的销毁逻辑
//在关闭了Activity时,如果Webview的音乐或视频,还在播放。就必须销毁Webview
//但是注意:webview调用destory时,webview仍绑定在Activity上
//这是由于自定义webview构建时传入了该Activity的context对象
//因此需要先从父容器中移除webview,然后再销毁webview:
if (webView !=null) {
ViewGroup parent=(ViewGroup) webView.getParent();
if (parent !=null) {
parent.removeView(webView);
}
webView.removeAllViews();
webView.destroy();
webView=null;
}
} catch (Exception e) {
}
super.onDestroy();
}
原因:当WebView加载页面出错时(一般为404 NOT FOUND,Android WebView会默认显示一个出错界面。当WebView加载出错时,会在WebViewClient实例中的onReceivedError(),还有onReceivedTitle方法接收到错误。
解决方法:自定义错误页面样式。
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
String host=Uri.parse(url).getHost();
if (!BuildConfig.IS_DEBUG) {
if (Arrays.binarySearch(domainList, host) < 0) {
//不在白名单内,非法网址,这个时候给用户强烈而明显的提示
} else {
//合法网址
}
}
}
原因:webView加载一些别人的url时候,有时候会发生证书认证错误的情况。
解决方法:要将正常的呈现页面给用户,我们需要忽略证书错误,需要调用WebViewClient类的onReceivedSslError方法,调用handler.proceed()来忽略该证书错误。
//在onResume里面设置setJavaScriptEnabled(true)。
@Override
protected void onResume() {
super.onResume();
if (mWebView !=null) {
mWebView.getSettings().setJavaScriptEnabled(true);
}
}
//在onStop里面设置setJavaScriptEnabled(false);
@Override
protected void onStop() {
super.onStop();
if (mWebView !=null) {
mWebView.getSettings().setJavaScriptEnabled(false)
}
}
原因:WebView页面中播放了音频,退出Activity后音频仍然在播放。
解决方法:需要在Activity的onDestory()中从父容器中移除WebView。
@Override
protected void onDestroy() {
try {
//有音频播放的web页面的销毁逻辑
//在关闭了Activity时,如果Webview的音乐或视频,还在播放。就必须销毁Webview
//但是注意:webview调用destory时,webview仍绑定在Activity上
//这是由于自定义webview构建时传入了该Activity的context对象
//因此需要先从父容器中移除webview,然后再销毁webview:
if (webView !=null) {
ViewGroup parent=(ViewGroup) webView.getParent();
if (parent !=null) {
parent.removeView(webView);
}
webView.removeAllViews();
webView.destroy();
webView=null;
}
} catch (Exception e) {
}
super.onDestroy();
}
原因:客户端内的WebView都是可以通过客户端的某个schema打开的,而要打开页面的URL很多都并不写在客户端内,而是可以由URL中的参数传递过去的。上面4.0.5 使用scheme协议打开链接风险已经说明了scheme使用的危险性。
解决方法:设置运行访问的白名单,或者当用户打开外部链接前给用户强烈而明显的提示。设置白名单操作其实和过滤广告是一个意思,这里你可以放一些合法的网址允许访问。
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
String host=Uri.parse(url).getHost();
if (!BuildConfig.IS_DEBUG) {
if (Arrays.binarySearch(domainList, host) < 0) {
//不在白名单内,非法网址,这个时候给用户强烈而明显的提示
} else {
//合法网址
}
}
}
原因:有些手机你如果webView加载的html里,有一些js一直在执行比如动画之类的东西,如果此刻webView 挂在了后台这些资源是不会被释放用户也无法感知。导致一直占有cpu 耗电特别快。
解决方法:WebView在后台的时候,会调用onStop方法,即此时关闭js交互,回到前台调用onResume再开启js交互。
//在onResume里面设置setJavaScriptEnabled(true)。
@Override
protected void onResume() {
super.onResume();
if (mWebView !=null) {
mWebView.getSettings().setJavaScriptEnabled(true);
}
}
//在onStop里面设置setJavaScriptEnabled(false);
@Override
protected void onStop() {
super.onStop();
if (mWebView !=null) {
mWebView.getSettings().setJavaScriptEnabled(false)
}
}
原因:WebView从Lollipop(5.0)开始webView默认不允许混合模式, https当中不能加载http资源, 而开发的时候可能使用的是https的链接,但是链接中的图片可能是http的,所以显示图片失败。
解决方案:需要设置开启。
*请认真填写需求信息,我们会在24小时内与您取得联系。