Android webview拦截请求

一、需求背景

如果想做webview的本地缓存或者拦截请求做其他的事情就设计到了拦截webview的请求。

二、解决方案

在Android自带的WebView中,如果需要对访问的URL或者资源进行拦截,主要涉及到WebViewClient中的三个方法:onPageStarted、shouldOverrideUrlLoading、shouldInterceptRequest。首先来分析onPageStarted方法和shouldOverrideUrlLoading方法,分别在两个方法以及onPageFinished方法中打印log

  • 当用户使用WebView的loadUrl方法开启一个网页时,其中onPageStarted方法会执行,而shouldOverrideUrlLoading则不会执行
  • 当用户继续点击网页内的链接时,onPageStarted和shouldOverrideUrlLoading均会执行,并且shouldOverrideUrlLoading要先于onPageStarted方法执行
  • 当用户点击网页中的链接后,点击back,返回历史网页时,onPageStarted会执行,而shouldOverrideUrlLoading不会执行

综上所述,当需要对访问的网页进行策略控制时,需要在onPageStarted方法中进行拦截,如下示例代码:

@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {  
    Log.d(TAG, "onPageStarted url is " + url);
    boolean res = checkUrl(url);
    //根据对URL的检查结果,进行不同的处理,
    //例如,当检查的URL不符合要求时,
    //可以加载本地安全页面,提示用户退出
    if (!res) {
        //停止加载原页面
        view.stopLoading();
        //加载安全页面
        view.loadUrl(LOCAL_SAFE_URL);
    }
}

然后,来分析一下shouldInterceptRequest(WebView view, String url),此方法从Android API 11(3.0)开始提供,位于WebViewClient 内,当用户使用WebView的loadUrl方法打开网页、点击网页中的链接、返回历史网页时,所有资源的加载均会调用shouldInterceptRequest方法

进行资源替换时,可以将网页资源,例如html、css、js、图片等存放在本地,在shouldInterceptRequest对WebView加载的资源进行拦截,当符合某种策略时,替换为本地的资源,资源的MIME类型可以采用以下方法获取: MimeTypeMap.getSingleton().getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(url))
示例:

@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
    Log.d(TAG, "shouldInterceptRequest : " + url);
    Uri uri = Uri.parse(url);
    String localPath = "file://" + Environment.getExternalStorageDirectory().getAbsoluteFile() + "/www" + uri.getPath();
    File file = new File(localPath);
    try {
        URL localUri = new URL(localPath);
        if (localUri != null) {
            InputStream is = localUri.openConnection().getInputStream();
            WebResourceResponse resourceResponse = new WebResourceResponse(
                        MimeTypeMap.getSingleton().getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(url))
                        , "UTF-8", is);
            Log.d(TAG, "replace " + MimeTypeMap.getFileExtensionFromUrl(url));
            return resourceResponse;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return super.shouldInterceptRequest(view, url);
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是Android WebView的用法大全: 1. 在XML布局文件中添加WebView组件 ``` <WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent"/> ``` 2. 在Java代码中获取WebView组件并设置WebViewClient ``` WebView webView = findViewById(R.id.webview); webView.setWebViewClient(new WebViewClient()); ``` 3. 加载网页 ``` webView.loadUrl("https://www.example.com"); ``` 4. 后退和前进 ``` if(webView.canGoBack()) { webView.goBack(); } if(webView.canGoForward()) { webView.goForward(); } ``` 5. 加载本地HTML页面 ``` webView.loadUrl("file:///android_asset/index.html"); ``` 6. 设置JavaScript支持 ``` webView.getSettings().setJavaScriptEnabled(true); ``` 7. 设置缩放 ``` webView.getSettings().setBuiltInZoomControls(true); webView.getSettings().setDisplayZoomControls(false); ``` 8. 处理网页中的URL ``` webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if(url.startsWith("mailto:")) { Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse(url)); startActivity(intent); return true; } view.loadUrl(url); return true; } }); ``` 9. 拦截网页中的请求 ``` webView.setWebViewClient(new WebViewClient() { @Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { if(request.getUrl().toString().endsWith(".png")) { try { InputStream inputStream = getAssets().open("image.png"); return new WebResourceResponse("image/png", "UTF-8", inputStream); } catch (IOException e) { e.printStackTrace(); } } return super.shouldInterceptRequest(view, request); } }); ``` 10. 处理页面加载事件 ``` webView.setWebViewClient(new WebViewClient() { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { progressBar.setVisibility(View.VISIBLE); } @Override public void onPageFinished(WebView view, String url) { progressBar.setVisibility(View.GONE); } @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { Toast.makeText(MainActivity.this, "Error: " + error.getDescription(), Toast.LENGTH_SHORT).show(); } }); ``` 11. 调用JavaScript代码 ``` webView.loadUrl("javascript:alert('Hello, world!')"); ``` 12. 与JavaScript交互 ``` webView.addJavascriptInterface(new Object() { @JavascriptInterface public void showToast(String message) { Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show(); } }, "android"); ``` 以上是Android WebView的用法大全,希望能对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联网小熊猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值