webview与移动应用程序中的本机代码之间的通信

use*_*688 9 android webview native-code ios

我必须开发一个电子商务移动应用程序.为了将产品展示到应用程序中,我必须使用指向移动网站的webview.与每个产品相关联的是"添加到购物篮"按钮.此按钮也是移动网站的一个元素.在移动应用程序的标签栏中(而不是在webview中),有一个篮子的图标,其中包含篮子的元素数量.webview如何知道用户已将一个或多个元素添加到购物篮并将此信息发送到可以更新购物篮图标的原生移动应用程序?

Dav*_*ams 14

的JavaScript.使用JavascriptInterface将WebView绑定到Android应用程序.以下是一些参考文档:在WebView中构建Web应用程序


Don*_*uck 6

要在 Javascript 代码中调用 Java(或 Kotlin)方法,首先创建一个类并使用以下命令标记需要在 Javascript 中使用的方法@JavascriptInterface

public class WebAppInterface{
    Activity _activity;

    WebAppInterface(Activity context){
        _activity = activity;
    }

    @JavascriptInterface
    public void javaMethodToBeCalledFromJavascript(){
        //Your code here
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,@JavascriptInterface方法必须是公共的,否则您无法从 Javascript 调用它们。

然后您需要创建该类的实例并将该实例作为参数传递给WebViews addJavascriptInterface

WebAppInterface interface = new WebAppInterface(this);    //this refers to the current activity
webView.addJavascriptInterface(interface, "Android");
Run Code Online (Sandbox Code Playgroud)

第一个参数addJavascriptInterface是包含您要从 Javascript 调用的方法的对象,第二个参数是在 Javascript 中调用的接口。由于在此示例中第二个参数是"Android",这将创建一个 Javascript 对象,该Android对象使用标记为 的方法进行调用@JavascriptInterface(如果您"Foo"作为第二个参数传递,则将调用 Javascript 对象Foo)。因此,要在 Javascript 中调用该javaMethodToBeCalledFromJavascript()方法,请执行以下操作:

Android.javaMethodToBeCalledFromJavascript();
Run Code Online (Sandbox Code Playgroud)

基础知识就是这么简单。然而,有一些事情需要了解,以避免花费大量时间进行调试。


最重要的是要知道从 Javascript 调用的 Java 对象是在单独的线程上运行的。这有两个主要的实际后果。

首先,Android 只允许您从 UI 线程访问 UI 元素。因此,以下代码将引发异常CalledFromWrongThreadException(尽管它可能看起来什么也没做,我稍后会讨论)

@JavascriptInterface
public void changeTextOnTextView(String newText){
    _activity.someTextView.setText(newText);
}
Run Code Online (Sandbox Code Playgroud)
Android.changeTextOnTextView("Hello World!");
Run Code Online (Sandbox Code Playgroud)

这是因为您只能在 的 UI 线程_activity.someTextView上访问_activity,但在这里您尝试从 Javascript 线程访问它。为了解决这个问题,使用activity的runOnUiThread方法:

@JavascriptInterface
public void changeTextOnTextView(String newText){
    _activity.runOnUiThread(() -> {
        _activity.someTextView.setText(newText);
    });
}
Run Code Online (Sandbox Code Playgroud)

其次,从 Javascript 线程抛出的任何未捕获的 Java 异常都被视为 Javascript 错误。这有多个问题。第一个问题是,默认情况下,AndroidWebView根本不显示 Javascript 错误。即使您解决了这个问题(无论是在 Javascript 端还是window.onerror在 Java 端,如此处答案之一所述,您都会遇到第二个问题,即 Javascript 错误只会告诉您“Java方法调用期间引发了异常”,但没有给您任何有关 Java 异常是什么或在 Java 代码中何处抛出异常的指示。

为了解决这个问题,您可以runOnUiThread按照上面的解释使用,因为 UI 线程上抛出的未捕获的 Java 异常将像往常一样运行,从而在 Android Studio 中为您提供详细的堆栈跟踪。如果您想捕获异常,您还可以在 Java 代码中使用 try/catch 块(但不能在 Javascript 代码中使用,否则您将无法获取有关异常的任何信息)。


归档时间:

查看次数:

19538 次

最近记录:

10 年,1 月 前