Вызывается ли setDownloadListener onDownloadStart после того, как веб-просмотр уже получает файл?
Правда ли, что WebView выполнит Http Get и загрузит полный файл, затем вызовет метод myDownloadStart(), и мой код снова загрузит файл?
В WebView, используемом в приложении Android, нам нужно обрабатывать загрузку PDF-файла. Я вижу поведение, которое, я думаю, имеет смысл, но оно кажется странным, поэтому я надеюсь, что кто-то может проверить для меня.
Когда WebView настроен, мы вызываем setDownloadListener() и создаем новый DownloadListener для обработки вызова метода onDownloadStart(). В методе onDownloadStart() мы используем HttpURLConnection для получения ресурса с нашего веб-сервера.
В сетевых трассировках я вижу два запроса Http Get, выполненных для одного и того же ресурса. Я предполагаю, что это потому, что веб-просмотр сначала выполняет Get для ресурса, а затем веб-просмотр выполняет свою собственную обработку и определяет, что он не может отобразить ресурс. Затем веб-просмотр вызывает метод onDownloadStart(), и мы получаем ресурс во второй раз.
Документы для SetDownloadListener говорят:
Зарегистрируйте интерфейс, который будет использоваться, когда контент не может быть обработан механизмом рендеринга и должен быть загружен вместо него. Это заменит текущий обработчик.
Веб-представление не будет знать, сможет ли оно отобразить ресурс, пока не получит ответ от сервера и не сможет прочитать возвращаемый тип содержимого. Таким образом, он должен сначала выполнить GET или HEAD, чтобы прочитать заголовки ответа. Таким образом, поведение двойной загрузки имеет смысл.
И некоторые последующие вопросы:
- Это обычная ситуация? Действительно ли большинство приложений, которые загружают файлы из веб-просмотра, загружают файл дважды? (это кажется дорогим, но я думаю, что это может происходить)
- Есть ли способ повторно использовать уже загруженный контент из первого запроса вместо повторного запроса?
- Почему WebView не использует метод Http HEAD в первом запросе, а не GET? (Я думаю, это сделало бы каждую гиперссылку двухэтапным процессом, и это было бы слишком дорого)
- Есть ли способ предотвратить дополнительную загрузку? Возможно, следует использовать shouldOverrideUrlLoading() для перехвата запроса?
1 ответ
Лучше начинать с ответа на свой 3. вопрос:
Я думаю, что WebView использует GET-метод для всех Ressources. И только после того, как он получает первые заголовки http этого запроса, WebView проверяет, есть ли заголовки, которые сообщают "сделать загрузку"
(например, заголовки, такие как Content-Disposition: Attachment; filename=example.html
)
Если не существует заголовка, который указывает на загрузку, WebView отобразит загрузку и содержимое в своем представлении.
onDownload
вызывается, если имеется заголовок загрузки (даже если его значение установлено как "встроенное").
Ответ на вопрос 2:
Я думаю, что в этом случае веб-просмотр НЕ загружает содержимое контента. В настоящее время я не знаю способ повторно использовать существующий запрос.
Ответ на вопрос 4
Если вы overide shouldInterceptRequest
как в этом примере: /questions/34190625/dobavlenie-polzovatelskih-zagolovkov-v-zaprosyi-resursov-webview-android/34190649#34190649 Вы можете изменить это поведение.