美文网首页
WebView的基础使用跟一些坑的集思录(后续碰到坑会继续添加)

WebView的基础使用跟一些坑的集思录(后续碰到坑会继续添加)

作者: 未扬帆的小船 | 来源:发表于2019-11-20 17:43 被阅读0次

    一、前言:

    本篇文章只是记录一下webview使用过程的基本用法跟自己碰到的一点坑,如果想看很完整版之类的可以看一下下面其他大神的几个文章:
    Android WebView 详解
    史上最全WebView使用,附送Html5Activity一份
    Android WebView:这是一份 详细 & 易懂的WebView学习攻略(含与JS交互、缓存构建等)

    (=_=!前面先说一下 免得浪费大家宝贵的时间)

    二、简介

    基于webkit引擎展现web页面的控件高低版本实现不同

    • Android 4.4前:各个安卓版本使用了不同的webkit版本的内核
    • Android 4.4后:使用了Chrome内核

    三、相关基础类

    webView相关类的大意图.png
    详情请看:Android WebView 详解 ,里面有很多常用api的中文注释

    四、基础使用:

    1. 在布局文件中直接放入<WebView>
    webView = findViewById(R.id.web)
    
    1. 在代码中添加
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            mWebView = new WebView(getApplicationContext());
            mWebView.setLayoutParams(params);
            mLayout.addView(mWebView);
    

    最基础的配置信息

     val webSettings = webView.settings 
     webSettings.javaScriptEnabled = true //支持js
     webView.webViewClient = object :WebViewClient(){
       //下面两种写法都可以让url在我们的webview中执行,而不会跳到系统的浏览器
    //            override fun shouldOverrideUrlLoading( view: WebView?, request: WebResourceRequest?): Boolean {
      //              view!!.loadUrl(request!!.url.toString())
      //              return true
      //          }
                  override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
                    return super.shouldOverrideUrlLoading(view, request)
                }
    
            }
    //加载url webView.loadUrl("https://www.baidu.com")
    

    ok,上面过后就可以简单的使用了。

    后面讲一下第二种方式的添加WebView的好处,看后面的 内存泄漏处理

    五、 本地加载文件

    1. 在android文件中assets目录下放相应的*.html文件
    2. 代码上调用
    mWebView.loadUrl("file:///android_asset/相应的文件名.html")
    

    ok 这样子就可以加载本地的文件了

    六、与js交互

    android、js交互几个种方式.png

    一定要先添加下面语句,启用Javascript

    settings.setJavaScriptEnabled(true); 
    
    1. Andorid调用js

    1.1 android执行js表达式

    // 弹出提示框
    web.loadUrl("javascript:alert('hello')");
    // 调用注入的jsobj.say方法
    web.loadUrl("javascript:jsobj.say('hello')"); 
    

    1.2 在API19后可异步执行JS表达式,并通过回调返回值

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        vWeb.evaluateJavascript("你好~", new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String value) {
               
            }
        });
    }
    

    2. Js调用Android

    2.1 注入对象到Javascript

    //调用
    web.addJavascriptInterface(new JsObject(), "TestObject")
    //增加JsObject类
    class  JsObject{
          @JavascriptInterface
          fun javacalljs(){
          Toast.makeText(this@CenterSystemFragment.context,"成功回调安卓",Toast.LENGTH_SHORT).show()
         }
          @JavascriptInterface
          fun javacalljswithargs(arg:String){
              Toast.makeText(this@CenterSystemFragment.context,"成功回调安卓$arg",Toast.LENGTH_SHORT).show()
          }
    }
    

    2.2 在WebViewClient#sholudOveriideUrlLoading()拦截

    webViewClient = object : WebViewClient() {
    //在网页上的所有加载都经过这个方法,这个函数我们可以做很多操作,
    //比如截取url的参数然后去做逻辑操作
      override fun shouldOverrideUrlLoading(view:WebView?,request: WebResourceRequest?): Boolean {
        view!!.loadUrl(request!!.url.toString())
         return true
     }
     }
    

    2.3 WebChromeClient# onJsAlert() onJsPrompt()等方法拦截js对话框

     mWebChromeClient = object : WebChromeClient() {
                override fun onJsPrompt(
                    view: WebView?,
                    url: String?,
                    message: String?,
                    defaultValue: String?,
                    result: JsPromptResult?
                ): Boolean {
                    return super.onJsPrompt(view, url, message, defaultValue, result)
                }
    
                override fun onJsConfirm(
                    view: WebView?,
                    url: String?,
                    message: String?,
                    result: JsResult?
                ): Boolean {
                    return super.onJsConfirm(view, url, message, result)
                }
    
                override fun onJsAlert(
                    view: WebView?,
                    url: String?,
                    message: String?,
                    result: JsResult?
                ): Boolean {
                    return super.onJsAlert(view, url, message, result)
                }
    
            }
    

    七 填坑纪实

    1. 内存泄漏

    • 在代码中添加webView并传入application context不挟持activity可以处理很大一部分的内存泄漏,就是本篇文章开头基础使用的第二种用法。
    • 销毁WebView
    if (vWeb != null) {
        vWeb.setWebViewClient(null);
        vWeb.setWebChromeClient(null);
        vWeb.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
        vWeb.clearHistory();
        ((ViewGroup) vWeb.getParent()).removeView(vWeb);
        vWeb.destroy();
        vWeb = null;
    } 
    

    2. Error inflating class android.webkit.WebView

    可以看下其它网友的处理方法 https://blog.csdn.net/qq_36347817/article/details/86625447
    如果是androidx 5.0 系统 webview闪退报这种问题问题的话,可以尝试一下下面的解决方案,具体我也没搞懂是怎么一回事,如果有懂的同学麻烦说一下

    public class LollipopFixedWebView extends WebView {
        public LollipopFixedWebView(Context context) {
            super(getFixedContext(context));
        }
    
        public LollipopFixedWebView(Context context, AttributeSet attrs) {
            super(getFixedContext(context), attrs);
        }
    
        public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(getFixedContext(context), attrs, defStyleAttr);
        }
    
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(getFixedContext(context), attrs, defStyleAttr, defStyleRes);
        }
    
        public LollipopFixedWebView(Context context, AttributeSet attrs, int defStyleAttr, boolean privateBrowsing) {
            super(getFixedContext(context), attrs, defStyleAttr, privateBrowsing);
        }
    
        public static Context getFixedContext(Context context) {
            return context.createConfigurationContext(new Configuration());
        }
    }
    

    相关文章

      网友评论

          本文标题:WebView的基础使用跟一些坑的集思录(后续碰到坑会继续添加)

          本文链接:https://www.haomeiwen.com/subject/kutoictx.html