2016-03-14 136 views
7

我在安卓Qt 5.5中使用QNetworkAccessManager时出现问题。通过http GET下载一个简单的小图形文件会导致大量垃圾收集调用,并在此期间锁定用户界面。后续的GET工作完美,没有这些GC调用。代码如下:QNetworkAccessManager - 第一个GET非常慢

void DownloadManager::downloadFile(QUrl fromUrl, QString toFilePath) { 

    _currentFilePath = toFilePath; 

    QNetworkRequest request; 
    request.setUrl(fromUrl); 

    qDebug() << "before"; 

    _currentReply = _mgr.get(request); 

    qDebug() << "after"; 

    connect(_currentReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError))); 
    connect(_currentReply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64,qint64))); 
    connect(_currentReply, SIGNAL(finished()), this, SLOT(downloadFinished())); 

} 

DownloadManager是没有任何特殊的功能,相关的GET请求一个自定义的QObject派生类。 _mgr是在DownloadManagers cTor期间分配的QNetworkAccessManager对象。

正如您所看到的,这仅仅是一个get请求的教科书示例,对此没有任何幻想。正如我所说:大多数情况下它都有效。只有第一个GET请求结束这样的:

D/ .../downloadmanager.cpp:61 (void DownloadManager::downloadFile(QUrl, QString)): before 
D/dalvikvm(13298): GC_CONCURRENT freed 2290K, 25% free 10911K/14407K, paused 2ms+3ms, total 29ms 
D/dalvikvm(13298): GC_CONCURRENT freed 501K, 25% free 10884K/14407K, paused 13ms+2ms, total 35ms 
D/dalvikvm(13298): GC_CONCURRENT freed 524K, 25% free 10892K/14407K, paused 12ms+3ms, total 36ms 
D/dalvikvm(13298): WAIT_FOR_CONCURRENT_GC blocked 6ms 
D/dalvikvm(13298): GC_CONCURRENT freed 537K, 25% free 10887K/14407K, paused 2ms+9ms, total 32ms 
D/dalvikvm(13298): WAIT_FOR_CONCURRENT_GC blocked 14ms 
D/dalvikvm(13298): GC_CONCURRENT freed 840K, 25% free 10899K/14407K, paused 12ms+3ms, total 38ms 
D/dalvikvm(13298): WAIT_FOR_CONCURRENT_GC blocked 11ms 
D/dalvikvm(13298): GC_CONCURRENT freed 1294K, 25% free 10901K/14407K, paused 2ms+2ms, total 27ms 
D/dalvikvm(13298): WAIT_FOR_CONCURRENT_GC blocked 11ms 
D/dalvikvm(13298): GC_CONCURRENT freed 1187K, 22% free 11330K/14407K, paused 2ms+2ms, total 30ms 
D/dalvikvm(13298): WAIT_FOR_CONCURRENT_GC blocked 15ms 
D/dalvikvm(13298): GC_CONCURRENT freed 1459K, 19% free 11919K/14535K, paused 13ms+4ms, total 64ms 
D/dalvikvm(13298): WAIT_FOR_CONCURRENT_GC blocked 18ms 
D/ .../downloadmanager.cpp:65 (void DownloadManager::downloadFile(QUrl, QString)): after 

我根本不明白是什么原因导致这么多GC发生 - 它大约需要一个完整的,以一个半秒,其他所有的工作了(一下载,应该需要一秒钟,而且,是异步,而不是锁定用户界面)。

附加信息:

  • 它始终只是触发此先下载。随后的下载,即使是完全相同的文件,也能完美地工作。

  • 如果在确切位置存在具有确切名称的文件,则无关紧要。下载文件,删除文件,重新下载应用程序并重新下载它会得到相同的结果 - 第一次获取速度慢,有GC,第二次很好。

  • 我调用QML文件中的所有内容,这会导致单例C++对象调用DownloadManager :: downloadFile。

  • 除了QML UI之外,其他应用程序中都没有运行其他任何应用程序。没有繁重的数据交换,没有其他线程的背景加载,没有任何东西

我会很感激任何解决这个问题的指针。

+0

'QNetworkAccessManager'产生一个带有自己事件循环的工作线程来处理网络请求。也许开始这个事件循环会对Java进行很多调用? –

回答

1

我没有试过Android,但我在Windows上遇到了同样的问题。因为这些都是相同的症状,所以我可能会说这可能是相同的原因,那就是实现在第一次get()调用时懒惰地加载了一些共享库。使用加密连接时尤其如此;在我的情况下,我可以在Visual Studio中看到19个DLL在第一次get()调用时加载。

解决此问题的一种方法是使用connectToHostconnectToHostEncrypted预连接到服务器,具体取决于您是否使用加密连接(例如HTTPS)。我在应用程序启动时调用它,但是任何时候UI闲置都应该没问题。然后,随后的get()调用将具有相同的性能,包括第一个,因为这些库已经加载并且连接已经建立。我假设连接到任何服务器将加载库。

有关一般错误(不特定于Android)的详细信息,请参见https://forum.qt.io/topic/65201/qnetworkaccessmanager-first-get-very-slow/14