Android和jS互调技术Demo实现

package com.loaderman.webviewdemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private WebView mWebView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mWebView = (WebView) findViewById(R.id.wv_test);
        WebSettings settings = mWebView.getSettings();
        settings.setJavaScriptEnabled(true);//开启js

        mWebView.loadUrl("file:///android_asset/demo.html");//加载本地网页
        mWebView.setWebChromeClient(new WebChromeClient());//此行代码可以保证js的alert弹窗正常弹出
        //核心方法, 用于处理js被执行后的回调
        mWebView.addJavascriptInterface(new JsCallback() {
            @JavascriptInterface//注意:此处一定要加该注解,否则在4.1+系统上运行失败
            @Override
            public void onJsCallback() {
                Toast.makeText(MainActivity.this, "js调用Android啦", Toast.LENGTH_SHORT).show();
            }
        }, "demo");//参1是回调接口的实现;参2是js回调对象的名称
    }
    //定义回调接口
    public interface JsCallback {
         void onJsCallback();
    }
    // android调用js
    public void androidCallJs(View view) {
        mWebView.loadUrl("javascript:wave()");
    }
}

 在main/assets下新建demo.html

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<script language="javascript">
    /* This function is invoked by the activity */
    function wave() {
        alert("Android调用Js啦");
    }

</script>
<body>a
<!-- Js调用Android代码 -->
<a onClick="window.demo.onJsCallback()">
    <div style="80px;
        margin:0px auto;
        padding:10px;
        text-align:center;
        border:2px solid #202020;">
        <img id="droid" src="android_normal.png"/><br>
        Click me!
    </div>
</a>
</body>

 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.loaderman.webviewdemo.MainActivity">
    <Button
        android:text="android调用js"
        android:layout_width="match_parent"
        android:onClick="androidCallJs"
        android:layout_height="wrap_content"/>
    <WebView
        android:id="@+id/wv_test"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

 添加网络权限:

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

 效果实现:


注意: js回调的方法的书写格式: onClick="window.demo.onJsCallback() 格式是: window.js回调对象的名称(要和java代码中设置的一致).回调方法名称(要和java代码中设置的一致)

Js调用Android的方式具有版本兼容问题. 经测试, 在2.2, 4.0+ 系统上运行稳定, 可以正常调用, 但是在2.3系统上运行时出现崩溃.原因是底层进行JNI调用时,把一个Java中的String对象当数组来访问了,最终导致虚拟机崩溃. 基本算是一个比较严重的BUG,没办法解决,所以如果说用WebView组件想在js和java之间相互调用的话就没办法适应所有机型.


 

原文地址:https://www.cnblogs.com/loaderman/p/6498288.html