一、简介:WebView是一个显示网页的视图。但是它不是一个普通的View,它比一般的View要庞大、复杂,其实它就是一个浏览器,相当于一个Google Chrome,当然它没有Google Chrome本身那么强大。它允许使用浏览器加载网页或者就在WebView内加载网页,早期它是使用WebKit渲染引擎来显示网页,在Android 4.4之后直接是基于chrome,然后chrome又是基于chromium内核。
如果要将Web应用程序(或只是网页)作为客户端应用程序的一部分提供,可以使用WebView进行操作。WebView类是Android的View类的子类,它允许你将网页显示为Activity布局的一部分。它不包括完全开发的Web浏览器的任何功能,例如导航控件或地址栏。默认情况下,所有WebView都会显示一个网页。

二、添加一个WebView到你的应用程序中。
1、在布局文件中添加WebView,方式就是类似于TextView
2、在Java代码中通过findViewById获取到WebView实例
3、webView.loadUrl(“http://www.baidu.com”);
前提:
1、添加上INTERNET权限
2、如果是https,那么这个是需要有官方认证的合法证书,类似于这种自签证书,使用webview去加载,会报错的,无法成功加载。
备注:从内存泄漏和更好的内存管理的角度,最好是在代码中去new一个webview,因为这种在布局文件中添加的方式,可能会因为布局文件的约束导致一定程度的内存泄漏。

三、启用JavaScript

WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);

有些网页如果不启用JavaScript是打开不了的,比如https://www.baidu.com
一般情况下建议启用JavaScript

四、将JavaScript代码绑定到Android代码
在开发专门针对Android应用程序中的WebView设计的Web应用程序时,你可以在JavaScript代码和客户端Android代码之间创建接口。例如,你的JavaScript代码可以调用Android代码中的方法来显示对话框,而不是使用JavaScript的alert()函数。
这里主要用到了addJavascriptInterface方法,详情可以参考
https://developer.android.com/guide/webapps/webview.html#AddingWebView 中的Binding JavaScript code to Android code章节,这里讲的比较详细。
这里我们也根据实际的应用实践,来举一个例子:

    //webviwe init的时候,执行下面这行代码
    mBinding.wv.addJavascriptInterface(new JsInterface(), "android");

    /**
     * 原生与Js交互的回调接口。
     * js端调用android,示例:
     * <button οnclick="android.feedback("gratingAbnormal_new;mouseGuardAbnormal_new")">feedback</button>
     */
    final class JsInterface {
        /**
         * @JavascriptInterface 注解是必须要有的,添加这个注解来将我们定义的方法暴露出去给web端调用。
         * 否则在web端是调用不了的。增加通过注解这个机制也是一种安全保证,否则web端可以随意调用系统方法。
         * 另外方法的修饰符也必须是public,否则web端也访问不了这个方法。
         */
        @JavascriptInterface
        public void feedback(String msg) {
            LogUtils.i("msg:" + msg);
            if (TextUtils.isEmpty(msg)) {
                return;
            }
            mParentAct.runOnUiThread(() -> {
                boolean isGrantingAbnormal = false, isMouseGuardAbnormal = false;
                boolean isGrantingAbnormalNewData = false, isMouseGuardAbnormalNewData = false;
                if (!"normal".equals(msg)) {
                    String[] flagArr = msg.split(";");
                    for (String flag : flagArr) {
                        if (flag.startsWith("gratingAbnormal")) {
                            isGrantingAbnormal = true;
                            if (flag.endsWith("_new")) {
                                isGrantingAbnormalNewData = true;
                            }
                        } else if (flag.startsWith("mouseGuardAbnormal")) {
                            isMouseGuardAbnormal = true;
                            if (flag.endsWith("_new")) {
                                isMouseGuardAbnormalNewData = true;
                            }
                        }
                    }
                }
                mParentAct.mEnvironmentalAlarmController.mGrantingAbnormal = isGrantingAbnormal;
                mParentAct.mEnvironmentalAlarmController.mMouseGuardAbnormal = isMouseGuardAbnormal;
                mParentAct.mEnvironmentalAlarmController.mGrantingAbnormalNewData = isGrantingAbnormalNewData;
                mParentAct.mEnvironmentalAlarmController.mMouseGuardAbnormalNewData = isMouseGuardAbnormalNewData;
                mParentAct.mEnvironmentalAlarmController.environmentalAlarm();
            });
        }
    }

五、处理页面导航
如果想让所有链接都在WebView中实现,可以这样写:

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new WebViewClient());

如果想做详细的控制,比如让外链通过浏览器访问,则这样写:

webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if (Uri.parse(url).getHost().equals("https://www.baidu.com")) {
                    return false;
                }
                /**
                 * 外链调用浏览器  往往这样是出于安全考虑
                 */
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                startActivity(intent);
                return true;
            }
        });

六、导航网页历史
当你的WebView覆盖URL加载时,它会自动累积访问的网页的历史记录。你可以通过goBack()和goForward()向后和向前浏览历史记录。
例如,对用户点击手机上的物理返回键的处理如下:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    // Check if the key event was the Back button and if there's history
    if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) {
        myWebView.goBack();
        return true;
    }
    // If it wasn't the Back key or there's no web page history, bubble up to the default
    // system behavior (probably exit the activity)
    return super.onKeyDown(keyCode, event);
}

七、加载缓冲条

webView.setWebChromeClient(new WebChromeClient(){  
            @Override  
            public void onProgressChanged(WebView view, int newProgress) {  
                super.onProgressChanged(view, newProgress);  
                progress.setVisibility(View.VISIBLE);  
                progress.setProgress(newProgress);  
            }  
        });
webView.setWebViewClient(new WebViewClient(){   
            @Override  
            public void onPageFinished(WebView view, String url) {  
                super.onPageFinished(view, url);  
                if (progress != null) {  
                    progress.setVisibility(View.GONE);  
                }  
            }  
        });  

八、WebView的缓存
缓存模式:
LOAD_CACHE_ONLY:不使用网络,只读取本地缓存数据。
LOAD_DEFAULT:如果页面没有强制任何特定行为(依赖服务端控制),如果本地有未过期的缓存,就会直接加载本地缓存,否则就请求网络。
LOAD_NORMAL:API level 17中已经废弃, 从API level 11开始作用同LOAD_DEFAULT模式。
LOAD_NO_CACHE:忽略本地缓存(就算有也不用),直接请求网络。
LOAD_CACHE_ELSE_NETWORK:只要本地有缓存,不管有没有过期,都使用本地缓存。否则就请求网络。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐