最近在混合开发中遇到一个问题,这里将问题及解决方案记录如下:
问题:
现在有这么个需求,webview中加载了一个H5界面(第三方应用提供的界面,如嵌入一个淘宝商品界面),在界面中有个按钮,点击时需要跳转到第三方APP中的相关界面,假如本地未安装则跳转去下载(可以自行设计下载方式,如直接跳转浏览器,或者自定义下载界面)。因为是第三方提供的H5界面链接,所以我们未知其实现逻辑,在接入的过程中发现点击按钮没有任何反应,既不会跳转去下载,也不会唤起对应的第三方APP应用。。。
解决方案:
经一番sou sou 搜,发现Android的WebView自身是支持网页唤起第三方App的,但是如果为WebView设置了自定义的WebViewClient,这个功能就失效了,另外我们没有做特别处理的话,webview不会直接下载对应的apk,所以需要我们对这种场景做处理。
(1)首先我们在WebViewClient的shouldOverrideUrlLoading(WebView view, String url) 方法中搞事情。
上面代码也很简单,就是对自定义的scheme做拦截直接跳转唤起第三方APP,假如本地没有安装则会抛如下异常
System.err: android.content.ActivityNotFoundException:
No Activity found to handle Intent { act=android.intent.action.VIEW ....},我们try-catch就可以了,这是标识字段isDownload仍然是初始值true,这样就可以继续搞事情了。
(2)然后我们又可以通过webview的setDownloadListener(DownloadListener listener)方法搞事情。
以上代码通过判断isDownload字段是否为true来跳转浏览器进行下载操作。
那可能有人会问为什么要设置isDownload字段呢?为什么在shouldOverrideUrlLoading做设置,在setDownloadListener中做判断管用呢?这个问题看一下如下的日志就知道了。
图中:1 后面对应的链接为待唤起APP对应的url; 2 处是调用webview的setDownloadListener方法。
由图我们可以看出来setDownloadListener方法在最后才会执行,所以这就是上面问题中为什么在shouldOverrideUrlLoading做设置,在setDownloadListener中做判断管用的原因。至于isDownload字段的作用是为了防止本地已经安装了待唤起的第三方APP,程序在执行时仍会走setDownloadListener监听,又一次跳转浏览器提醒用户下载,通过这么控制提升用户体验。
总结一下,开篇说到的问题解决方案我们可以归结两点:
(1)在WebViewClient的shouldOverrideUrlLoading中拦截url唤起第三方APP,假如本地未安装时try-catch异常,
(2)同时通过webview的setDownloadListener设置下载监听,并设置下载标识,只有链接是下载链接时才会走回调,我们可以在回调中进行下载操作。