带你溜WebView

331 阅读4分钟

在平常的开发中我们一般都会使用到混合开发,比如H5+原生,如果你的app使用到H5开发,那么webview使用是不可或缺的。所以掌握WebView的知识是多么重要。 本文要带你溜WebView,让你掌握WebView的基本开发,包括与javaSript的交互。 先看下效果图

弹框.jpg

toast.jpg

这里首先点击“hello world” 然后javaSript弹出一个alert弹框,接着JavaScript调用java的clickText函数,通过回调,弹出一个toast提示。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="lwj.com.webview.WebViewActivity">
    <WebView
        android:id="@+id/id_webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</android.support.constraint.ConstraintLayout>

布局就一个webview显示网页

public class WebViewActivity extends AppCompatActivity {
    private static final String TAG = "WebViewActivity";
    private WebView webView;
    private Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_view);
        webView = (WebView) this.findViewById(R.id.id_webview);
        WebSettings webSetting = webView.getSettings();
        webSetting.setDefaultTextEncodingName("utf-8");
        webSetting.setJavaScriptEnabled(true);//支持js
        webSetting.setUseWideViewPort(false);//设置此属性,可任意缩放比例
        webSetting.setTextZoom(100);//设置字体,相对于正常字体的百分比
        webSetting.setLoadWithOverviewMode(true);
        webSetting.setDomStorageEnabled(true);// 开启DOM storage
        webView.setWebChromeClient(webChromeClient);
        webView.setWebViewClient(webViewClient);

        String s1 = getHtmlStr("hello world");
        webView.loadData(s1, "text/html", "utf-8");

        //与js交互
        JsToAndroidInterface jsToAndroid = new JsToAndroidInterface();
        jsToAndroid.setOnClickListener(new JsToAndroidInterface.OnTextClickListener() {

            @Override
            public void onTextClick(final String str) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(WebViewActivity.this,str,Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
        webView.addJavascriptInterface(jsToAndroid, JsToAndroidInterface.INTERFACE_NAME);
    }

    /**
     * html数据
     * @param str
     * @return
     */
    public static String getHtmlStr(String str) {
        StringBuilder builder = null;
        try {
            builder = new StringBuilder();
            builder.append("<html><head>");
            builder.append(" <script language=\"javascript\">function s(){\n" +
                    "alert(\""+str+"!\");\n" +
                    "window.clickOnAndroid.clickText(\""+str+"\");\n" +
                    "}</script>");
            builder.append("</head><body><div class=\"container\"><div class=\"content\">");
            builder.append("<a href=\"javascript:void(0);\" onclick=\"s()\">").append(str).append("</a>");
            builder.append("</div></div></body></html>");
        } catch (Exception e) {
            e.printStackTrace();
        }

        return builder.toString();
    }


    /**
     * 处理各种通知
     * 请求事件相关
     */
    private WebViewClient webViewClient = new WebViewClient() {
        /**
         * 开始加载页面回调
         * @param view
         * @param url
         * @param favicon
         */
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            Log.i(TAG, "onPageStarted");
            super.onPageStarted(view, url, favicon);
        }

        /**
         * 拦截url跳转
         * @param view
         * @param url
         * @return
         */
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            //当前的webview跳转
            webView.loadUrl(url);
            return true;
        }

        /**
         * 在每一次请求资源时回调
         * @param view
         * @param request
         * @return
         */
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
            Log.i(TAG, "shouldOverrideUrlLoading");
            return super.shouldOverrideUrlLoading(view, request);
        }

        /**
         * 加载完成回调
         * @param view
         * @param url
         */
        @Override
        public void onPageFinished(WebView view, String url) {
            Log.i(TAG, "onPageFinished");
            super.onPageFinished(view, url);
        }

        /**
         * 加载错误回调
         * 在这做错误处理
         * @param view
         * @param request
         * @param error
         */
        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            Log.i(TAG, "onReceivedError");
            super.onReceivedError(view, request, error);
        }

        /**
         * https错误回调
         * 可做错误处理
         * @param view
         * @param request
         * @param errorResponse
         */
        @Override
        public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
            Log.i(TAG, "onReceivedHttpError");
            super.onReceivedHttpError(view, request, errorResponse);
        }

        /**
         * 加载页面资源回调
         * @param view
         * @param url
         */
        @Override
        public void onLoadResource(WebView view, String url) {
            Log.i(TAG, "onLoadResource");
            super.onLoadResource(view, url);
        }
    };
    /**
     * 处理浏览器相关的事件
     * 如处理JavaScript的对话框
     * 图标、title、加载进度
     */
    private WebChromeClient webChromeClient = new WebChromeClient() {
        /**
         * javasript 的alert弹框调用
         * @param view
         * @param url
         * @param message
         * @param result
         * @return
         */
        @Override
        public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
            Log.i(TAG, "onJsAlert");
            AlertDialog dlg = new AlertDialog.Builder(WebViewActivity.this).create();
            dlg.setTitle("提示");
            dlg.setMessage(message);
            dlg.setButton(AlertDialog.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface arg0, int arg1) {
                    result.confirm();
                }
            });
            dlg.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface arg0) {
                    result.cancel();
                }
            });
            dlg.show();
            return true;
        }

        /**
         * js的Confirm弹框
         * @param view
         * @param url
         * @param message
         * @param result
         * @return
         */
        @Override
        public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
            AlertDialog dlg = new AlertDialog.Builder(WebViewActivity.this).create();
            dlg.setTitle("提示");
            dlg.setMessage(message);
            dlg.setButton(AlertDialog.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface arg0, int arg1) {
                    result.confirm();
                }
            });
            dlg.setButton(AlertDialog.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface arg0, int arg1) {
                    result.cancel();
                }
            });
            dlg.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface arg0) {
                    result.cancel();
                }
            });
            dlg.show();
            return true;
        }

        /**
         * 处理js prompt弹框
         * @param view
         * @param url
         * @param message
         * @param defaultValue
         * @param result
         * @return
         */
        @Override
        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
            Log.i(TAG, "onJsPrompt");
            return super.onJsPrompt(view, url, message, defaultValue, result);
        }

        /**
         * 加载网页进度条
         * @param view
         * @param newProgress
         */
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            Log.i(TAG, "onProgressChanged" + newProgress);
            super.onProgressChanged(view, newProgress);
        }

        /**
         * 网页的title
         * @param view
         * @param title
         */
        @Override
        public void onReceivedTitle(WebView view, String title) {
            Log.i(TAG, "onReceivedTitle" + title);
            super.onReceivedTitle(view, title);
        }
    };

    /**
     * 实现在历史页面中 Back
     * 要在当前 Activity
     * 中处理并消费掉该 Back事件:
     */
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
            webView.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
}

这里首先通过WebSettings设置webview支持的类型,包括与JavaScript交互的设置,然后加载html数据,并且设置与JavaScript交互的对象(JsToAndroidInterface),还有关于WebViewClient和WebChromeClient介绍,里面方法的作用与处理,具体的可以看注释,最后对webView.goBack()的处理.

public class JsToAndroidInterface {

    public static final String INTERFACE_NAME = "clickOnAndroid";
    private OnTextClickListener mClickListener;

    /**
     * 供js调用函数
     * @param str
     */
    @JavascriptInterface
    public void clickText(final String str)
    {
        if(mClickListener != null)
        {
            mClickListener.onTextClick(str);
        }
    }

    /**
     * 回调接口
     */
    public interface OnTextClickListener
    {
        void onTextClick(String str);
    }

    /**
     * 设置回调
     * @param listener
     */
    public void setOnClickListener(OnTextClickListener listener)
    {
        mClickListener = listener;
    }
}

这是与JavaScript交互的对象,JavaScript调用clickText,通过回调给用户调用. 看了本文,应该都了解webview的常用知识了吧.