Android中webview的使用,重点处理图片和附件下载

本文详细介绍WebView的基本使用,包括加载不同类型的网页、配置WebSettings、实现JS与Android的交互,以及处理图片和附件下载等实用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. webview基本使用:

    //加载网页链接
    webView.loadUrl("http://keithxiaoy.com");
    //加载本地assets目录下的网页
    webView.loadUrl("file:///android_asset/keithxiaoy.html");
    //加载手机本地的html页面
    webView.loadUrl("content://com.android.htmlfileprovider/sdcard/keithxiaoy.html");
    //加载 HTML 页面的一小段内容。参数1:需要截取展示的内容、参数2:展示内容的类型、参数3:字节码
    webView.loadData(String data, String mimeType, String encoding)
    webview.loadData(Html.fromHtml(notice.getContent()).toString(), "text/html", "UTF-8");
    
  2. webview配置:

    WebSettings settings = mWebView.getSettings();
    settings.setNeedInitialFocus(false);// default true 初始不让任何元素抢占焦点
    settings.setDomStorageEnabled(true);//false 的话localStorage不能使用
    settings.setAppCacheEnabled(false);// default false true需要配合setAppCachePath使用
    settings.setAppCachePath("");
    settings.setJavaScriptEnabled(true);//default false 如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript
    settings.setUseWideViewPort(true);//是否支持HTML meta viewport,default false
    settings.setLoadWithOverviewMode(false);//是否可以按屏幕宽度适配内容,如果上面设置true,那这里默认是false
    settings.setSupportZoom(false);//是否允许本身的按钮缩放和手势缩放,default true ,此配置不影响zoomIn和zoomOut()
    //以下3项是禁止使用file协议加载内容
    settings.setAllowFileAccess(false);
    settings.setAllowFileAccessFromFileURLs(false);//通过 file mUrl 加载的 Javascript 读取其他的本地文件 .建议关闭
    settings.setAllowUniversalAccessFromFileURLs(false);
    settings.setJavaScriptCanOpenWindowsAutomatically(true);//影响JavaScript的window.open()方法 default false
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.1
        //适配5.0不允许http和https混合使用情况
        settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
    }
    
  3. WebChromeClient

    private class MyWebChromeClient extends WebChromeClient {
        //设置标题
        @Override
        public void onReceivedTitle(WebView view, String title) {
            super.onReceivedTitle(view, title);
        }
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            if (newProgress<100){
                if (progressBar.getVisibility() == View.GONE) progressBar.setVisibility(View.VISIBLE);
                progressBar.setProgress(newProgress);//改变进度条
            }else if (newProgress ==100){
                progressBar.setVisibility(View.GONE);
            }
            super.onProgressChanged(view, newProgress);
        }
    }
    
  4. js调用Android原生方法:

    //1. 先声明一个类,可以理解为js的对象,对象的名称是下面的第二部的第二个参数
    class MyJavaInterFace{
        @JavascriptInterface//加上注解,表明js可有调用这个方法
        public void openFile(String url){
            FileDisplayActivity.show(ArticleDetailActivity.this,url);
        // startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
        }
    }
    //2. webview和声明的类产生关联,第二个参数相当于js中的对象名称(上面类的别名),前端js通过webInterFace.openFile(参数)调用原生方法并传递参数
    webview.addJavascriptInterface(new MyJavaInterFace(),"webInterFace");
    
  5. Android调用js方法

     final String params = "android参数111111";//需要给前端传递的参数
     button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //调用js方法,以javascript表明调用的是前端js函数,funFromJs是前端js定义的函数名称,传递参数时注意函数后的单引号和双引号,我也不知道啥意思。
            webview.loadUrl("javascript:funFromJs('"+params+"')");
        }
    });
    
        /**
         * 4.4以上可用 evaluateJavascript 效率高
         */
        private void load(String jsCode) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                //
                evaluateJavascript(jsCode, null);
            } else {
                loadUrl(jsCode);
            }
        }
    //在Android中打印js中的console信息,以便进行联调
    private class MywebChromeClient extends WebChromeClient {
        @Override
        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
            TLog.e("level:"+consoleMessage.messageLevel()+",message:"+consoleMessage.message()+",sourceId:"+consoleMessage.sourceId()+",lineNumber:"+consoleMessage.lineNumber());
            return super.onConsoleMessage(consoleMessage);
        }
    }
    
  6. 处理后退

     private boolean doubleBackToExit = false;
    /** 处理回退逻辑 */
     @Override
     public void onBackPressed() {
         //可以回退则回退到上一页面
         if (webview.canGoBack()){
             webview.goBack();
         }else if (!webview.canGoBack()){
             if (doubleBackToExit){
                 super.onBackPressed();
                 return;
             }
             //不可以回退,提示
             Toast.makeText(MainActivity.this,"再按一次退出",Toast.LENGTH_SHORT).show();
             doubleBackToExit = true;//第一次按返回键后,标志值为true,两秒中后置位false,这两秒之内连续按返回键就可以退出
             new Handler().postDelayed(new Runnable() {
                 @Override
                 public void run() {
                     doubleBackToExit = false;
                 }
             }, 2000);
         }
    
  7. 处理图片和附件下载

    //这里处理了webview里有超链接附件是不能下载的问题,识别超链接后可以调用原生方法,调用系统浏览器下载附件,files[i].removeAttribute('href')是阻止超链接的默认行为,防止超链接点击时在webview内打开空白页,图片通过修改maxWidth属性修改为图片最大宽度为手机宽度的90%,这里保证js是在html代码加载完毕再执行,这里可以使用前端IDE,比如Vscode先把js代码写好后之间粘贴在AndroidStudio中,以免烦人的string拼接错误
    String varjs = "<script>\n" +
            "        window.onload = function () {\n" +
            "            var files = document.getElementsByTagName(\"a\");\n" +
            "            for (var i = 0; i < files.length; i++) {\n" +
            "                var fileUrl = files[i].getAttribute('href')\n" +
            "                if (fileUrl.endsWith('pdf') || fileUrl.endsWith('doc') || fileUrl.endsWith('docx') || fileUrl.endsWith('xls') || fileUrl.endsWith('xlsx')) {\n" +
            "                    files[i].removeAttribute('href')\n" +
            "                    files[i].onclick = function () {\n" +
            "                        webInterFace.openFile(fileUrl)\n" +
            "                    }\n" +
            "                }\n" +
            "            }\n" +
            "            var $imgs = document.getElementsByTagName(\"img\");\n" +
            "            for (var p = 0; p < $imgs.length; p++) {\n" +
            "                $imgs[p].style.maxWidth = '90%';\n" +
            "                $imgs[p].style.height = 'auto';\n" +
            "            }\n" +
            "        }\n" +
        //防止webview里使用相对路径,和使用retrofit的baseUrl性质一样,这里把js和原生的html组装为真正执行的html代码,这里加载的是html代码片段,没有html和body标签,索性就直接把js代码方法放在了html代码的最前面,如果html是一个完整的,复杂的操作可以使用Jsoup解析后进行复杂操作jsoup地址`https://jsoup.org/`
        webview.loadDataWithBaseURL(baseUrl,varjs + newsArticle.getContent(), "text/html", "UTF-8",null);
    

其他文章
8. Android webview 与 js(Vue) 交互
9. Android H5交互Webview实现localStorage数据存储
10.如何设计一个优雅健壮的Android WebView

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值