android - 是不是webview已经获取到文件后调用setDownloadListener onDownloadStart?

标签 android android-webview

WebView 是否真的会执行 Http Get 并下载完整的文件,然后调用我的 onDownloadStart() 方法,然后我的代码再次下载文件?

在 Android 应用程序中使用的 WebView 中,我们需要处理 PDF 文件的下载。我看到我认为有道理的行为,但它看起来很奇怪,所以我希望有人可以为我验证。

设置 WebView 后,我们调用 setDownloadListener() 并创建一个新的 DownloadListener 来处理 onDownloadStart() 方法调用。在 onDownloadStart() 方法中,我们使用 HttpURLConnection 从我们的 Web 服务器获取资源。

在网络跟踪中,我看到对同一资源执行了两个 Http Get 请求。我假设这是因为 webview 首先对资源执行 Get,然后 webview 进行自己的处理并确定它无法呈现资源。然后 webview 调用 onDownloadStart() 方法,我们第二次检索资源。

SetDownloadListener 的文档说:

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.

在从服务器获得响应并且可以读取返回的内容类型之前,webview 不知道它是否可以呈现资源。因此,它必须首先执行 GET 或 HEAD 来读取响应 header 。因此,双重下载行为似乎是有道理的。

还有一些后续问题:

  1. 这种情况常见吗?大多数从 webview 下载文件的应用程序真的会下载文件两次吗? (这看起来很昂贵,但我认为它可能正在发生)
  2. 有没有办法重用第一次请求中已下载的内容,而不是再次请求?
  3. 为什么 WebView 在第一次请求时不使用 Http HEAD 方法而不是 GET? (我想这会使每个超链接成为一个两步过程,而且成本也很高)
  4. 有什么方法可以阻止额外的下载吗?也许使用 shouldOverrideUrlLoading() 来拦截请求?

最佳答案

最好从您的3 的答案开始。问题:

我认为 WebView 对所有资源都使用 GET 方法。只有在它获得此请求的第一个 http header 后,WebView 才会检查是否有 header 告诉“进行下载”

(例如像 Content-Disposition: Attachment; filename=example.html 这样的标题)

如果不存在指向下载的 header ,WebView 将在其 View 中显示负载和内容。

onDownload 在有下载 header 时调用(即使其值设置为“内联”)。

问题 2 的答案:

我认为在那种情况下,webview 不会加载内容的内容。 目前我不知道重用现有请求的方法。

问题 4 的答案

如果你覆盖shouldInterceptRequest

就像这个例子:https://stackoverflow.com/a/29811280/2377961 你可以改变这种行为。

关于android - 是不是webview已经获取到文件后调用setDownloadListener onDownloadStart?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12535414/

相关文章:

java - 滑动刷新覆盖在 webview 中滚动我的网页中的菜单

安卓 : Html Anchor Link works only once in webview

android - android wear 中的 WebView 在运行时出错

android - Android 上的 EditText 输入数字作为密码样式

android - 在 Android Xamarin 中使用我的日历的权限

android - 使用 Zxing 条码扫描器导致 SecurityException

android - 如何恢复SQLite数据库目录?

android - 如何生成具有用户定义长度的字符串?

android webview 内容不可选择

java - WebView - 无法添加窗口 - token null 不适用于应用程序