美文网首页Android开发Android技术知识
Android WebView和JavaScript交互

Android WebView和JavaScript交互

作者: 贼厉害 | 来源:发表于2017-05-28 22:18 被阅读0次

    现在移动应用几乎都是 Hybrid App(混合模式移动应用)是指介于web-app、native-app这两者之间的app,兼具“Native App良好用户交互体验的优势”和“Web App跨平台开发的优势”。
    而hybrid的实现关键在于打通Java和JavaScript之间的交互。
    在Android开发中我们是使用WebView控件来加载HTML页面的,WebView默认为我们提供了让Java和HTML页面中JavaScript脚本交互的能力。

    1 Java调用JavaScript

    java调用JavaScript非常简单,只需要执行下面代码即可。

    mWebView.loadUrl("javascript:methodName(parameterValues)");
    

    不过其中还需要注意几个细节,我们先来看个例子,然后再介绍需要注意的地方。

    IDE:Android Studio

    先写一个H5的页面test.html,把它放在了assets资源文件下

    <!DOCTYPE HTML>
    
    <head>
        <title>java调用JavaScript</title>
    </head>
    <!--提供给java调用的方法-->
    <script type="text/javascript"/>
        function alertMessage(message) {
            alert(message)
        }
    </script>
    
    </HTML>
    

    xml布局:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        android:id="@+id/id_linearlayout"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <Button
            android:id="@+id/id_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="alertMessage"/>
    
        <WebView
            android:id="@+id/id_webview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"></WebView>
    </LinearLayout>
    

    Activity代码:

    public class MyWebView extends AppCompatActivity {
        private WebView mWebView;
        private Button mButton;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_my_web_view);
            mWebView = (WebView) findViewById(R.id.id_webview);
            mButton = (Button) findViewById(R.id.id_button);
            loadURL();
        }
    
        private void loadURL() {
            mWebView.setWebViewClient(new WebViewClient());//此方法可以在webview中打开链接而不会跳转到外部浏览器
            mWebView.setWebChromeClient(new WebChromeClient());//各种内容的渲染需要使用webviewChromClient去实现,比如alert()方法
            mWebView.loadUrl("file:///android_asset/test.html");
        }
    
        private void initEvents() {
            mButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mWebView.loadUrl("javascript:alertMessage(\""+"Message"+"\")");//注意转义字符
                }
            });
        }
    
        //重写onKeyDown,当浏览网页,WebView可以后退时执行后退操作。
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) {
                mWebView.goBack();
                return true;
            }
            return super.onKeyDown(keyCode, event);
        }
    }
    

    需要注意的是setWebViewClient(new WebViewClient())和setWebChromeClient(new WebChromeClient())方法。

    • setWebViewClient(new WebViewClient())可以在webview中打开链接而不会跳转到外部浏览器
    • setWebChromeClient(new WebChromeClient())方法可以给WebView设置一个WebChromeClient,各种内容的渲染需要使用webviewChromClient去实现,比如alert()方法,如果这个方法没写不会有alert()方法的效果。
    01.jpg

    点击按钮之后效果

    02.jpg

    2 JavaScript调用Java

    WebView提供了一个名为WebSettings的工具类实现让Webview中的JavaScript脚本调用android应用的Java方法,实现方式很简单。

    • 调用与WebView关联的WebSettings实例的setJavaScriptEnabled方法使能调用的功能
    • 调用WebView的addJavaScriptInterface方法将应用中的Java对象暴露给JavaScript
    • 在JavaScript脚本中调用暴露的Java对象的方法

    增加H5页面代码

    <!DOCTYPE HTML>
    
    <head>
        <title>h5</title>
    </head>
    <!--调用java方法-->
    <body>
        <input type="button" value=" 打印Log" onclick=" javaObject.printLog('printLog');">
        <input type="button" value=" 显示Toast" onclick=" javaObject.showToast();">
    </body>
    
    <!--提供给java调用的方法-->
    <script type="text/javascript"/>
        function alertMessage(message) {
            alert(message)
        }
    </script>
    
    </HTML>
    

    我们新建提供给JavaScript调用的Java类javaObject

    public class javaObject {
        private Context context;
        private final String TAG = "javaObjectLog";
    
        public javaObject(Context context) {
            this.context = context;
        }
        
        public void printLog(String mes){
            Log.i(TAG, mes);
        }
    
        
        public void showToast(){
            Toast.makeText(context, "Toast", Toast.LENGTH_SHORT).show();
        }
    }
    

    增加Activity代码

    public class MyWebView extends AppCompatActivity {
        private WebView mWebView;
        private Button mButton;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_my_web_view);
            mWebView = (WebView) findViewById(R.id.id_webview);
            mButton = (Button) findViewById(R.id.id_button);
            loadURL();
            initEvents();
        }
    
        private void initEvents() {
            mButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mWebView.loadUrl("javascript:alertMessage(\""+"Message"+"\")");
                }
            });
        }
    
        private void loadURL() {
            mWebView.setWebViewClient(new WebViewClient());//此方法可以在webview中打开链接而不会跳转到外部浏览器
            mWebView.setWebChromeClient(new WebChromeClient());//各种内容的渲染需要使用webviewChromClient去实现,比如alert()方法
            WebSettings webSettings = mWebView.getSettings();//
            webSettings.setJavaScriptEnabled(true);//
            mWebView.loadUrl("file:///android_asset/test.html");
    
            mWebView.addJavascriptInterface(new javaObject(this), "javaObject");//把javaObject类对象暴露给JavaScript
        }
    
    
        //重写onKeyDown,当浏览网页,WebView可以后退时执行后退操作。
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) {
                mWebView.goBack();
                return true;
            }
            return super.onKeyDown(keyCode, event);
        }
    }
    
    
    03.jpg

    这种方法是官方提供的,但是却存在极大地安全隐患,所以从Android 4.2开始,Google就修复了这个漏洞,所以如果你测试机是4.2以上你会发现并没有成功调用暴露的方法。我们想要安全的使用上面的方法,唯一需要改动的就是对暴露给JavaScript调用的方法添加@JavascriptInterface注解。修改如下:

    public class javaObject {
        private Context context;
        private final String TAG = "javaObjectLog";
    
        public javaObject(Context context) {
            this.context = context;
        }
        @JavascriptInterface
        public void printLog(String mes){
            Log.i(TAG, mes);
        }
    
        @JavascriptInterface
        public void showToast(){
            Toast.makeText(context, "Toast", Toast.LENGTH_SHORT).show();
        }
    }
    

    输出结果

    04.jpg 05.png

    相关文章

      网友评论

        本文标题:Android WebView和JavaScript交互

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