Android JS交互详解

发布时间:2023-05-21

一、WebView实现

现在的APP开发越来越注重交互性,前端技术也在不断发展,所以如何在Android中实现JS交互成为了一个急需解决的问题。本篇文章就从多个方面详细阐述Android JS交互,并给出具体的代码实现。 WebView是Android中内置的一个浏览器组件,在页面加载时会自动执行页面内的JavaScript。通过WebView可以实现Android与JS的交互。下面给出一个简单的示例,演示如何通过WebView调起Android原生的Toast组件。

WebView webView = findViewById(R.id.web_view);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new Object() {
    @JavascriptInterface
    public void showToast(String message) {
        Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
    }
}, "app");
webView.loadUrl("file:///android_asset/index.html");

上述代码中,首先通过findViewById获取到WebView组件并使其支持JavaScript。然后通过addJavascriptInterface方法向JS注入一个名为“app”的接口,该接口有一个名为showToast的方法,用于在Android中调起Toast。最后通过loadUrl方法加载HTML文件。下面给出JS代码片段。

<button onclick="app.showToast('Hello World')">调用Toast</button>

上述代码中,通过一个按钮触发调用showToast方法,传递一个字符串参数“Hello World”,调起Android原生的Toast。通过上述代码,我们可以看到Android与JS的交互非常方便,只需要通过addJavascriptInterface方法注入一个接口即可。

二、JSBridge实现

WebView虽然可以实现Android与JS的交互,但其存在一些安全性问题,因为addJavascriptInterface方法有一个漏洞,即允许你暴露Java对象给JS调用,在一定程度上增加了攻击者的威胁。为了解决这个问题,JSBridge应运而生,JSBridge基于WebView的特点实现了安全性更高的交互方式。 下面给出JSBridge库中的具体代码实现。

implementation 'com.github.lzyzsd:jsbridge:1.0.4'
WebView webView = findViewById(R.id.web_view);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new Object() {
    @JavascriptInterface
    public void showToast(String message) {
        Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
    }
}, "app");
webView.loadUrl("file:///android_asset/index.html");
BridgeWebView bridgeWebView = new BridgeWebView(this);
bridgeWebView.loadUrl("file:///android_asset/jsbridge.html");

上述代码中,首先通过implementation引入JSBridge库,并使WebView组件支持JavaScript,并注入一个名为“app”的接口,其中包含一个名为showToast的方法。然后通过BridgeWebView组件加载HTML文件。下面给出JS代码片段。

<button onclick="javascript:android.showToast('Hello World')">调用Toast</button>

上述代码中,调用showToast方法时通过javascript:android前缀的方式,直接调用到了注入的接口方法,跨平台交互更加高效、安全。

三、React Native实现

React Native是Facebook推出的一种跨平台移动应用开发框架,能够通过JavaScript语言来构建原生移动应用。React Native基于执行JavaScript代码的方式来跨平台成为了一个实现跨平台开发的利器,因此在Android与JS交互中也能够发挥巨大的作用。 下面给出React Native中实现JS交互的代码示例。

1、Java代码

public class MainActivity extends ReactActivity {
    @Override
    protected String getMainComponentName() {
        return "example";
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ReactRootView rootView = new ReactRootView(this);
        setContentView(rootView);
        ReactInstanceManager mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("index.android.bundle")
                .setJSMainModulePath("index")
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();
        rootView.startReactApplication(mReactInstanceManager, "example", null);
    }
    @ReactMethod
    public void showToast(String message) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }
}

上述代码中,首先继承ReactActivity,并复写getMainComponentName方法。然后在onCreate方法中创建ReactRootView组件,并通过ReactInstanceManager实现React Native环境的初始化,最后调用startReactApplication方法加载React Native组件,并注入一个名为“example”的接口,其中包含一个名为showToast的方法。

2、JS代码

import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, TouchableOpacity} from 'react-native';
import {NativeModules} from 'react-native';
export default class App extends Component {
    render() {
        return (
            <View style={styles.container}>
                <TouchableOpacity onPress={() => NativeModules.MainActivity.showToast('Hello World')} style={styles.btn}>
                    <Text style={{color: '#ffffff'}}>调用Toast</Text>
                </TouchableOpacity>
            </View>
        );
    }
}

上述代码中,在引入NativeModules模块后,直接调用MainActivity中注入的showToast方法即可实现Android与JS的交互。

四、jQuery Mobile实现

jQuery Mobile是一个开源的,跨平台的,针对移动设备的JavaScript框架,它整合了HTML5、CSS3以及jQuery核心库的功能,能够实现跨平台开发和UI实现。下面给出jQuery Mobile的代码实现方式,这里以调用Android的Toast组件为例。

<!DOCTYPE html>
<html>
<head>
    <title>jQuery Mobile Example</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" href="./jquery.mobile-1.4.5.min.css" />
    <script src="./jquery-1.11.1.min.js"></script>
    <script src="./jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
    <div data-role="page" id="page">
        <div data-role="header">
            <a href="#" id="show-button" class="ui-btn-right">Show</a>
            <img src="./android.png" style="max-width: 100%;" />
            <h1>Android <span id="title-text"></span></h1>
        </div>
        <div data-role="content">
            <!-- Content goes here -->
        </div>
        <div data-role="footer">
            <h1>Footer</h1>
        </div>
        <script>
            $("#show-button").click(function() {
                var message = "Hello World";
                window.location.href = "app://showToast?message=" + message;
            });
        </script>
    </div>
</body>
</html>

上述代码中,在点击Show按钮后,调用了一个名为app://showToast的URI。下面给出Android原生代码的实现方式。

webView.setWebViewClient(new WebViewClient() {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url.startsWith("app://showToast")) {
            String message = Uri.decode(url.substring(18));
            showToast(message);
            return true;
        }
        return super.shouldOverrideUrlLoading(view, url);
    }
});
@JavascriptInterface
public void showToast(String message) {
    Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
}

上述代码中,通过WebViewClient的重写,实现拦截app://showToast的URI,并通过showToast方法实现调起Android原生的Toast组件。

五、总结

本篇文章从WebView、JSBridge、React Native和jQuery Mobile四个方面详细阐述了Android JS交互的实现方式,并给出了具体的代码实现,希望读者可以通过本文更加深入地了解Android与JS交互,并在实际开发中灵活运用。