3月16日

本文详细介绍了在Android 4.2及以上版本中,如何正确地在WebView中注入Java对象,避免因JS调用时引发的TypeError问题。包括注入步骤的变化、安全性考虑以及官方文档说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1调试AppcanBase工程时遇到以下问题:

I/chromium(21003):[INFO:CONSOLE(1)] "Uncaught TypeError: Object [object Object] has nomethod 'test_startActivityForResult'", source:  (1)

分析:

此问题是在WebView中打开web页面,然后在web页面中通过js方法回调部分native的功能时出现的。

解决方法:

Android4.2及以上版本对于js的支持方式有改变导致查找资料,使用如下方法解决:

 

Webview注入Java对象注意事项

 

在android4.2以前,注入步骤如下:

webview.getSetting().setJavaScriptEnable(true);

classJsObject {

    public String toString() { return"injectedObject"; }

 }

 webView.addJavascriptInterface(new JsObject(),"injectedObject");

 

 

Android4.2及以后,注入步骤如下:

webview.getSetting().setJavaScriptEnable(true);

classJsObject {

    @JavascriptInterface

    public String toString() { return"injectedObject"; }

 }

 webView.addJavascriptInterface(new JsObject(),"injectedObject");

 

4.2之前向webview注入的对象所暴露的接口toString没有注释语句@JavascriptInterface,而4.2及以后的则多了注释语句@JavascriptInterface

 

经过查官方文档所知,因为这个接口允许JavaScript控制宿主应用程序,这是个很强大的特性,但同时,在4.2的版本前存在重大安全隐患,因为JavaScript可以使用反射访问注入webview的java对象的publicfields,在一个包含不信任内容的WebView中使用这个方法,会允许攻击者去篡改宿主应用程序,使用宿主应用程序的权限执行java代码。因此4.2以后,任何为JS暴露的接口,都需要加

@JavascriptInterface

注释,这样,这个Java对象的fields 将不允许被JS访问。

官方文档说明:

 

From the Android 4.2 documentation:

Caution: If you've set your targetSdkVersion to 17 or higher,you must add the @JavascriptInterface annotation to any method that you wantavailable your web page code (the method must also be public). If you do notprovide the annotation, then the method will not accessible by your web pagewhen running on Android 4.2 or higher.

注:如果将targetSdkVersion设置为17或者更高,但却没有给暴露的js接口加@JavascriptInterface注释,则logcat会报如下输出:

E/Web Console: Uncaught TypeError: Object [object Object] has nomethod 'toString'

 

public void addJavascriptInterface (Object object, String name)

Added in API level 1

Injects the supplied Java object into thisWebView. The object is injected into the JavaScript context of the main frame,using the supplied name. This allows the Java object's methods to be accessedfrom JavaScript. For applications targeted to API level JELLY_BEAN_MR1 andabove, only public methods that are annotated with JavascriptInterface can be accessed from JavaScript. For applications targeted toAPI level JELLY_BEAN orbelow, all public methods (including the inherited ones) can be accessed, seethe important security note below for implications.

Note that injected objects will not appear in JavaScript untilthe page is next (re)loaded. For example:

 class JsObject {
    @JavascriptInterface
    public String toString() { return "injectedObject"; }
 }
 webView.addJavascriptInterface(new JsObject(), "injectedObject");
 webView.loadData("", "text/html", null);
 webView.loadUrl("javascript:alert(injectedObject.toString())");

IMPORTANT:

  • This method can be used to allow JavaScript to control the host application. This is a powerful feature, but also presents a security risk for applications targeted to API level JELLY_BEAN or below, because JavaScript could use reflection to access an injected object's public fields. Use of this method in a WebView containing untrusted content could allow an attacker to manipulate the host application in unintended ways, executing Java code with the permissions of the host application. Use extreme care when using this method in a WebView which could contain untrusted content.
  • JavaScript interacts with Java object on a private, background thread of this WebView. Care is therefore required to maintain thread safety.
  • The Java object's fields are not accessible.

Parameters

object

the Java object to inject into this WebView's JavaScript context. Null values are ignored.

name

the name used to expose the object in JavaScript

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值