在网路应用中,我们会经常从网路上下载数据或使用网路上的图片等.这些图片在我们的应用中,有可能被反复利用.如果没有cache的机制,我们的应用就会反复地发送请求,并下载同样的数据,一遍又一遍.这样不光浪费我们的流量,而且有可能造成用户界面的流畅性.今天在我们的例程中,我们来教大家如何来创建一个网路的cache,并被我们的应用所使用.
创建一个Cache的目录及路径
QString getCachePath()
{
QString writablePath = QStandardPaths::
writableLocation(QStandardPaths::DataLocation);
qDebug() << "writablePath: " << writablePath;
QString absolutePath = QDir(writablePath).absolutePath();
qDebug() << "absoluePath: " << absolutePath;
absolutePath += "/cache/";
// We need to make sure we have the path for storage
QDir dir(absolutePath);
if ( dir.mkpath(absolutePath) ) {
qDebug() << "Successfully created the path!";
} else {
qDebug() << "Fails to create the path!";
}
// QString path = absolutePath + "/" + filename;
qDebug() << "cache path: " << absolutePath;
return absolutePath;
}
writablePath: "/home/phablet/.local/share/networkaccessmanagerfactory.liu-xiao-guo"
absoluePath: "/home/phablet/.local/share/networkaccessmanagerfactory.liu-xiao-guo"
Successfully created the path!
cache path: "/home/phablet/.local/share/networkaccessmanagerfactory.liu-xiao-guo/cache/"
创建NetworkAccessManagerFactory
class MyNetworkAccessManagerFactory : public QQmlNetworkAccessManagerFactory
{
public:
virtual QNetworkAccessManager *create(QObject *parent);
};
QNetworkAccessManager *MyNetworkAccessManagerFactory::create(QObject *parent)
{
qDebug() << "it is being called!";
QNetworkAccessManager *nam = new QNetworkAccessManager(parent);
QString path = getCachePath();
QNetworkDiskCache* cache = new QNetworkDiskCache(parent);
cache->setCacheDirectory(path);
nam->setCache(cache);
return nam;
}
在这里,我们创建了一个我们需要的NetworkAccessManager,并创建了一个QNetworkDiskCache.在Qt应用中,在默认的情况下,是没有任何的cache的.更加详细的阅读可以参阅文章"Q
NetworkAccessManager". 我们把我们需要的cache目录路径传人到我们的QNetworkDiskCache当中去.
加载NetworkAccessManagerFactory到我们的QML engine中去
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQuickView view;
qDebug() << "Original factory: " << view.engine()->networkAccessManagerFactory();
qDebug() << "Original manager: " << view.engine()->networkAccessManager();
QNetworkDiskCache* cache = (QNetworkDiskCache*)view.engine()->networkAccessManager()->cache();
qDebug() << "Original manager cache: " << cache;
view.engine()->setNetworkAccessManagerFactory(new MyNetworkAccessManagerFactory);
view.setSource(QUrl(QStringLiteral("qrc:///Main.qml")));
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.show();
return app.exec();
}
在这里我们通过如下的方法:
view.engine()->setNetworkAccessManagerFactory(new MyNetworkAccessManagerFactory);
把我们需要的Factory加载到我们的QML engine中.在上面,我们也展示了在没有设置Factory之前的信息:
Original factory: 0x0
Original manager: QNetworkAccessManager(0x268a60)
Original manager cache: QObject(0x0)
在QML中发送网路请求
import QtQuick 2.0
import Ubuntu.Components 1.1
/*!
\brief MainView with a Label and Button elements.
*/
MainView {
// objectName for functional testing purposes (autopilot-qt5)
objectName: "mainView"
// Note! applicationName needs to match the "name" field of the click manifest
applicationName: "networkaccessmanagerfactory.liu-xiao-guo"
/*
This property enables the application to change orientation
when the device is rotated. The default is false.
*/
//automaticOrientation: true
// Removes the old toolbar and enables new features of the new header.
useDeprecatedToolbar: false
width: units.gu(60)
height: units.gu(85)
Page {
title: i18n.tr("networkaccessmanagerfactory")
Image {
anchors.fill: parent
source: "http://v1.qzone.cc/avatar/201308/08/21/22/52039b7e538f5649.jpg!200x200.jpg"
fillMode: Image.PreserveAspectCrop
}
}
}
在这里,我们利用Image来发送一个网路请求,并查看我们的图片是否已经在cache里:
我们可以查看一下我们的cache目录里的情况:
在这里,我们的确看见一个 cache的文件,并且它的大小和我们实际的文件大小相似.