4

Is it true that the WebView will perform an Http Get and download the complete file then it calls calls my onDownloadStart() method and my code downloads the file again?

In a WebView used in an Android application we need to handle downloading a PDF file. I'm seeing behavior which I guess makes sense, but it seems odd so I'm hoping someone can verify for me.

When the WebView is set up we call setDownloadListener() and create a new DownloadListener to handle the onDownloadStart() method call. In the onDownloadStart() method we use an HttpURLConnection to get the resource from our web server.

In network traces I see two Http Get requests performed for the same resource. I assume this is because the webview first does a Get on the resource, then the webview does its own processing and determines that it cannot render the resource. The webview then calls the onDownloadStart() method and we retrieve the resource a second time.

The docs for SetDownloadListener say:

Register the interface to be used when content can not be handled by the rendering engine, and should be downloaded instead. This will replace the current handler.

The webview would not know if it can render the resource until it gets a response from the server and can read the content-type returned. So, it must first do a GET or a HEAD to read the response headers. So, the double download behavior seems to make sense.

And, some follow up questions:

  1. Is this a common situation? Do most apps that download files from within a webview really download the file twice? (that seems expensive but I think it may be happening)
  2. Is there a way to reuse the already downloaded content from the first request rather than requesting it again?
  3. Why doesn't the WebView use the Http HEAD method on the first request rather than GET? (I guess this would make every hyperlink a two step process and that would be expensive too)
  4. Is there a way I can prevent the extra download? Perhaps using shouldOverrideUrlLoading() to intercept the request?
Michael Levy
  • 13,097
  • 15
  • 66
  • 100
  • 2
    [Another question with a similar subject](http://stackoverflow.com/q/11801787/1023092) did not get any accepted answer recently (linked for reference). – Joe Sep 25 '12 at 21:23
  • 1
    this solved the problem https://stackoverflow.com/a/65684942/8258305 – Mohd Qasim Jan 12 '21 at 13:33
  • Hello. How did you fix it? I mean prevent double request to server? I know url which I need to prevent. – runia Jan 24 '22 at 17:50
  • We never fixed it. We just lived with double downloads. BTW, this was about ten years ago. I'm not sure if this behavior still occurs or if there is a different work around now. – Michael Levy Jan 25 '22 at 21:21

1 Answers1

2

Its better when a beginn with the answer to your 3. question:

I think WebView uses GET-method for all Ressources. And only after it gets the first http Headers of this request WebView checks if there are headers that tell "do a download"

(e.g. headers like Content-Disposition: Attachment; filename=example.html)

If no header exists which points to a download, WebView will display load and the content in its view.

onDownload is called if there is a download header (even if its value are set to "inline").

Answer to question 2:

I think in that case the webview does NOT load the content of the content. Currently i don`t know a way to reuse the existing request.

Answer to question 4

If you overide shouldInterceptRequest

like in this example: https://stackoverflow.com/a/29811280/2377961 You could change this behavoir.

Radon8472
  • 4,285
  • 1
  • 33
  • 41