美文网首页
Android Native与H5交互

Android Native与H5交互

作者: 王灵 | 来源:发表于2019-03-11 00:09 被阅读0次

Android开发过程中我们或多或少都会用到WebView,使用WebView来展示一些需要经常变动的界面,也易于维护。同时另一方面hybrid App开发现在用的也越来越多了。其中native和h5之间的交互更是必不可少的。具体Android中是如何和h5交互的?或者说Android中是如何和js交互的。

使用WebView加载网页

webView.loadUrl("https://www.baidu.com");
但是大多数情况下可没这么简单,比如网页内部链接的跳转、返回键的处理、特定地址的处理、加载进度和进度条的处理;下面是一个简单的示例

public class JSActivity extends BaseActivity {
    WebView webView;
    ProgressDialog progressDialog;

    @Override
    public int getLayoutId() {
        return R.layout.ac_js;
    }

    @Override
    public void initData() {
        super.initData();
        webView = getView(R.id.web_view);
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                //我们可以在这里拦截特定的rl请求,然后进行自己要的操作
                if (url.equals("file:///android_asset/test2.html")) {
                    Log.e(TAG, "shouldOverrideUrlLoading: " + url);
                    return true;
                } else {
                    //这里我们自己重新加载新的url页面,防止点击链接跳转到系统浏览器
                    webView.loadUrl(url);
                    return true;
                }
            }

            /**
             * 界面打开的回调
             */
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                if (progressDialog != null && progressDialog.isShowing()) {
                    progressDialog.dismiss();
                }
                //弹出菊花
                progressDialog = new ProgressDialog(JSActivity.this);
                progressDialog.setTitle("提示");
                progressDialog.setMessage("软软正在拼命加载……");
                progressDialog.show();

            }

            /**
             * 界面打开完毕的回调
             */
            @Override
            public void onPageFinished(WebView view, String url) {
                //隐藏菊花:不为空,正在显示。才隐藏关闭
                if (progressDialog != null && progressDialog.isShowing()) {
                    progressDialog.dismiss();
                }
            }
        });
        webView.setWebChromeClient(new WebChromeClient() {
            /**
             * 进度改变的回调
             * WebView:就是本身
             * newProgress:即将要显示的进度
             */
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                if (progressDialog != null && progressDialog.isShowing())
                    progressDialog.setMessage("软软正在拼命加载……" + newProgress + "%");
            }

        });
    }

    @Override
    public void action() {
        super.action();
        webView.loadUrl("https://www.baidu.com");
    }

    @Override
    public void onBackPressed() {
        if (webView.canGoBack()) {
            //返回上一个页
            webView.goBack();
            return;
        }
        super.onBackPressed();
    }
}
上面只是简单的html展示,但实际开发中我们需要与html进行交互;Native调用JS,JS调用Native,
  • java调用js分两种情况:有返回值和无返回值
    无返回值时直接
    webView.loadUrl("javascript:showInfoFromJava()");
    showInfoFromJava()是js方法
    有返回值时需要使用mWebView.evaluateJavascript()方法
webView.evaluateJavascript("sum(1,2)", new ValueCallback<String>() {
                    @Override
                    public void onReceiveValue(String value) {
                        tvShow.setText("调用sun(1,2)的返回值是: " + value);
                    }
                });
  • js调用java方法
    在android 4.2以上可以直接使用@javascriptinterface注解来声明,下面是在一个本地java方法
    public void addJavascriptInterface(Object object, String name);
    object参数:在object对象里面添加我们想要在Js里面调用的Android方法;name可以理解为实例 。在js中的调用就是 实例.方法名 ;
    java代码
webView.addJavascriptInterface(new Object() {
            //定义要调用的方法
            //msg由js调用的时候传递
            @JavascriptInterface
            public void showToast(String msg) {
                Toast.makeText(getApplicationContext(),
                        msg, Toast.LENGTH_SHORT).show();
            }
        }, "JSTest");

js代码

function showToast(){
JSTest.showToast("我是被JS执行的Android代码");
}

在下面贴出的实例代码中,还有一种在同一实例中定义多个方法的方式。
JS2Activity.class

public class JS2Activity extends BaseActivity {
    WebView webView;
    Button b1, b2;
    TextView tvShow;

    @Override
    public int getLayoutId() {
        return R.layout.ac_js2;
    }

    @Override
    public void initData() {
        super.initData();
        webView = getView(R.id.web_view);
        b1 = getView(R.id.bt_o);
        b2 = getView(R.id.bt_t);
        tvShow = getView(R.id.show_data);

        //首先设置Webview支持JS代码
        webView.getSettings().setJavaScriptEnabled(true);

        b1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                webView.loadUrl("javascript:showInfoFromJava('Native传递给JS的信息')");
                webView.loadUrl("javascript:showInfoFromJava()");
            }
        });
        b2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                webView.evaluateJavascript("sum(1,2)", new ValueCallback<String>() {
                    @Override
                    public void onReceiveValue(String value) {
                        tvShow.setText("调用sun(1,2)的返回值是: " + value);
                    }
                });
            }
        });
        webView.addJavascriptInterface(new Object() {
            //定义要调用的方法
            //msg由js调用的时候传递
            @JavascriptInterface
            public void showToast(String msg) {
                Toast.makeText(getApplicationContext(),
                        msg, Toast.LENGTH_SHORT).show();
            }
        }, "JSTest");
        webView.addJavascriptInterface(new JsInterface(this), "JsInterface");
    }

    @Override
    public void action() {
        super.action();
        webView.loadUrl("file:///android_asset/test.html");
    }

    @SuppressLint({"SetJavaScriptEnabled", "AddJavascriptInterface"})
    class JsInterface {
        private Context mContext;

        public JsInterface(Context context) {
            this.mContext = context;
        }


        @JavascriptInterface
        public String getName() {
            return TAG;
        }

        @JavascriptInterface
        public String getPass() {
            return getPass();
        }
    }
}

test.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>菜鸟教程(runoob.com)</title>
    <script>

function sum(a,b){
return a+b;
}
function showInfoFromJava(){
document.getElementById("demo").innerHTML="Java成功调的JS方法";
}

function showToast(){
JSTest.showToast("我是被JS执行的Android代码");
}
function getName(){
var name=JsInterface.getName();
document.getElementById("demo").innerHTML="JS调用Native方法的返回值: "+name;
}


</script>
</head>
<body>

<h1>我的第一个 JavaScript 程序</h1>
<p id="demo">这是一个段落</p>

<button type="button" onclick="showToast()">JS调用Native无返回值函数</button>
<button type="button" onclick="getName()">JS调用Native有返回值函数</button>

</body>
</html>

相关文章

网友评论

      本文标题:Android Native与H5交互

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