JS 与 Native APP 互动示例

1. 网页端 JS 调用 Native APP 中的代码

2. Native APP 调用 JS 端的代码

3. 它们之间的数据传递如何实现

4. 代码实现效果如下图:

  • Manifest.xml 中添加权限

    <uses-permission android:name="android.permission.INTERNET" />
    
  • MainActivity.java

    package com.demo.thorn.jsandnativeappdemo;
    
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.support.v7.app.AlertDialog;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.KeyEvent;
    import android.view.View;
    import android.webkit.JavascriptInterface;
    import android.webkit.JsResult;
    import android.webkit.WebChromeClient;
    import android.webkit.WebResourceError;
    import android.webkit.WebResourceRequest;
    import android.webkit.WebSettings;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;
    import android.widget.Button;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity {
    
        private WebView mWebView;
        private WebSettings mWebSettings;
        private Button btnDoJS;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            btnDoJS = findViewById(R.id.btn_fun);
            mWebView = findViewById(R.id.wv_content);
            mWebSettings = mWebView.getSettings();
    
            mWebSettings.setJavaScriptEnabled(true);
            mWebSettings.setDefaultTextEncodingName("UTF-8");
            mWebView.addJavascriptInterface(this,"androidTag");//传入类对象,传入 androidTag 作为调用标志
            mWebView.setWebViewClient(new MyWebViewClient());//传入 MyWebViewClient 对象,达到接收 HTML 传递的点击动作
            mWebView.setWebChromeClient(new MyWebChromeClient());//传入 MyWebChormeClient 对象,达到对话框可用的目的
    
            mWebView.loadUrl("file:///android_asset/test.html");
    
    
            btnDoJS.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    mWebView.loadUrl("javascript:doSomething()");// Activity 中调用 JS 的方法,可以加参数传值
    
                    /* 如果调用 JS 时,需要获得返回值,则调用 evaluateJavascript 这个方法,示例如下:
                    mWebView.evaluateJavascript("sum(1,2)", new ValueCallback<String>() {
                        @Override
                        public void onReceiveValue(String value) {
                            Log.e(TAG, "onReceiveValue value=" + value);
                        }
                    });
                    */
                }
            });
        }//onCreate 结束
    
        /*HTML 中被调用的方法*/
        @JavascriptInterface
        public void showToast(String text) {
            Toast.makeText(this, text, Toast.LENGTH_LONG).show();
        }
    
        /*HTML 中被调用的方法*/
        @JavascriptInterface
        public void toAnotherAcitity(){
            Intent intent2 = new Intent(MainActivity.this,SecondActivity.class);
            startActivity(intent2);
        }
    
        /*HTML 中被调用的方法*/
        @JavascriptInterface
        public void showDialog() {
            new AlertDialog
                    .Builder(this)
                    .setTitle("Title Here")
                    .setCancelable(true)
                    .setNegativeButton("cacel", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            showToast("negative");
                        }
                    })
                    .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            showToast("positive");
                        }
                    })
                    .setMessage("messages here ")
                    .show();
        }
    
        private class MyWebViewClient extends WebViewClient {
    
            /*官方文档:Give the host application a chance to take over the control when a new url is about to be loaded in the current WebView.*/
            /*在加载一个新的 URL 链接之前进行的操作(一般都是对一些 URL 进行拦截)*/
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if(url.equals("http://www.qq.com/")){
                    showToast("拦截了 QQ 网站");
                    return true;// 返回 true 表示拦截本次跳转;返回 false 表示继续跳转
                }else if(url.endsWith("test")){
                    toAnotherAcitity();
                    return true;
                }
                return false;
            }
    
            /*如果加载某个页面出错,跳转到本地的一个错误展示页面*/
            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);
                mWebView.loadUrl("file:///android_asset/errorPage.html");//加载本地的错误页面
                Log.i("jin",error.toString());
            }
        }
    
        //继承 WebChromeClient 管理 JS 调用 Native APP 得事件
        public class MyWebChromeClient extends WebChromeClient {
            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
    
    
                return super.onJsAlert(view, url, message, result);
            }
    
            @Override
            public void onReceivedTitle(WebView view, String title) {
                super.onReceivedTitle(view, title);
                Log.i("jin","title="+title.toString());
            }
        }
    
        /*用于实现网页浏览的“返回”功能*/
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
    
            if(mWebView.canGoBack()&& keyCode == KeyEvent.KEYCODE_BACK){
                mWebView.goBack();
                return true;
            }
            return super.onKeyDown(keyCode, event);
        }
    }
    
  • activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 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"
        android:orientation="vertical"
        tools:context="com.demo.thorn.jsandnativeappdemo.MainActivity">
    
        <WebView
            android:layout_weight="1"
            android:id="@+id/wv_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
        <Button
            android:text="这里 Activity 调用 JS"
            android:id="@+id/btn_fun"
            android:layout_width="match_parent"
            android:layout_height="50dp" />
    
    </LinearLayout>
    
  • test.html(assets\test.html)

    <html>
        <head>
            <meta charset="utf-8"/>
            <title>Js调用Android</title>
    
            </head>
        <body>
            <div>
                <dl>
                    <dd><a href="http://www.qq.com">被拦截的URL</a></dd>
                    <dd><a href="http://www.baidu.com">正常的URL</a></dd>
                    <dd><a href="http://www.qq.test" >想在 shouldOverrideUrlLoading 中调用intent跳转,但失败了</a></dd>
                    <dd><input type="button" value="调用方法NativeAPP中的方法跳转" onclick="androidTag.toAnotherAcitity()"/></dd>
                    <dd><input type="button" value="Toast 提示" onclick="androidTag.showToast('调用了 showToast 方法');"/></dd>
                    <dd><input type="button" value="列表对话框" onclick="androidTag.showDialog();"/></dd>
                    <dd> <input type="button" value="Alert" onclick="alertSomeThing()"/></dd>
    
                    <dd><div id="content"><h2>这是初始内容</h2></div> </dd>
                </dl>
            </div>
        </body>
        <script>
            function alertSomeThing(){
                // 弹出一个框
                alert("alert something to show ");
            }
    
            function doSomething(){
                //改变 id 为 content 中的值
                     document.getElementById("content").innerHTML =("测试1111111111111");
            }
        </script>
    
    </html>
    
  • errorPage.html(assets\errorPage.html)

    <html>
        <head>
            <meta charset="utf-8"/>
            <title>ErrorPage</title>
        </head>
        <body>
            <a>不好意思,出错了哟</a>
        </body>
    </html>
    

源代码

    https://github.com/ThornFUN/JsAndNativeAPPDemo

猜你喜欢

转载自blog.csdn.net/baidu_33221362/article/details/80947302