QNetworkAccessManager – сначала GET очень медленно

У меня проблема с использованием QNetworkAccessManager в Qt 5.5 на Android. Загрузка простого, маленького графического файла через http GET приводит к множеству вызовов сбора мусора и блокировке пользовательского интерфейса за это время. Последующие GET работают безупречно и без этих вызовов GC. Код выглядит следующим образом:

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 – это произвольный класс, основанный на QObject, без каких-либо специальных функций, которые имеют отношение к запросу get. _mgr – объект QNetworkAccessManager, выделенный во время DownloadManagers cTor.

Как вы можете видеть, это всего лишь пример учебника запроса на получение, ничего особенного в этом нет. И, как я сказал: это работает, по большей части. Только первый запрос на получение заканчивается следующим образом:

 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 произойдет – для полной работы требуется полтора с половиной секунды (для загрузки, которая должна занимать долю секунды и, более того, быть асинхронным, а не блокировать Пользовательский интерфейс).

Дополнительная информация:

  • Это всегда только первая загрузка, которая вызывает это. Последующие загрузки, даже для одного и того же файла, работают безупречно

  • Неважно, есть ли файл в точном месте с точным именем или нет. Скачивая файл, удаляя его, возвращаясь в приложение и перезагружая его, вы получаете те же результаты – первый get медленный и имеет GC, второй работает отлично.

  • Я вызываю все это из файла QML, что заставляет объект singleton c ++ вызывать DownloadManager :: downloadFile.

  • Помимо интерфейса QML, в приложении ничего не работает. Отсутствие тяжелых обменов данными, отсутствие фоновой загрузки на другие потоки, ничего.

Я был бы благодарен за любые указания на решение этого.

Я не пробовал Android, но у меня была такая же проблема в Windows. Поскольку те же симптомы, я бы сказал, что это, вероятно, та же самая причина, которая заключается в том, что реализация лениво загружает некоторую общую библиотеку при первом вызове. Это особенно верно при использовании зашифрованного соединения; В моем случае я вижу в Visual Studio, что при первом вызове get () загружается 19 DLL.

Один из способов обойти это – предварительно подключиться к серверу с помощью connectToHost или connectToHostEncrypted, в зависимости от того, используете ли вы зашифрованное соединение (например, HTTPS) или нет. Я звоню, что при запуске приложения, но в любое время, когда пользовательский интерфейс неактивен, все должно быть хорошо. Затем последующие вызовы get () будут иметь одинаковую производительность, в том числе первую, поскольку библиотеки загружены и соединение уже установлено. Я предполагаю, что подключение к любому серверу будет загружать библиотеки.

См. https://forum.qt.io/topic/65201/qnetworkaccessmanager-first-get-very-slow/14 для получения подробной информации об общей ошибке (не относящейся к Android).