欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android和jS互调技术Demo实现

程序员文章站 2022-04-18 13:58:16
...
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="width: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"/>

 效果实现:

Android和jS互调技术Demo实现


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

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