java script android_android 中java和javascript交互

android的WebView是一个非常强大的控件,本文主要针对其简单使用和笔者在使用时所遇到的问题做一些总结。

目录

一、WebView中Java与javascript交互

二、使用时遇见android版本兼容的问题

三、关于代码混淆导致JS和Java无法交互的问题

四、Android和IOS共同开发的小提示

一、WebView中Java与javascript交互

1.这是要和js交互的注入接口类:

public final classJavascriptMethodClass1 {

// 用Handler是保证交互执行在UI线程中privateHandler handler;publicJavascriptMethodClass1(Handler handler) {this.handler =handler;

}

// 该注解主要是避免4.2以上的系统版本无法交互的问题

@JavascriptInterfacepublic void test(finalString teststr) {

handler.post(newRunnable() {

@Overridepublic voidrun() {

Toast.makeText(getApplicationContext(), teststr, Toast.LENGTH_LONG).show();

}

});

}

@JavascriptInterfacepublic voidtest1() {

handler.post(newRunnable() {

@Overridepublic voidrun() {//调用js代码

webView.loadUrl("javascript:testJavaCall('这是java调js的方法')");

}

});

}

}

2.这是交互的代码,其中data里的window.testObject.test('这是js掉java的Test方法')是调用java的代码

webView.getSettings().setJavaScriptEnabled(true);

webView.addJavascriptInterface(new JavascriptInteerface(), "testObject");//测试的HTML代码

String data ="

TEST1

";//如果是网页,直接用loadUrl(url)方法

webView.loadDataWithBaseURL(null, data, "text/html", "utf-8", null);

二、使用时遇见android版本兼容的问题

WebView存在android系统版本升级导致的兼容性问题。本文主要讨论的是java和js的交互问题。4.2版本之前和4.2版本(包含)之后接入js是有所区别的。

在之前,笔者使用的注入交互接口类如下:

public final classJavascriptInteerface{public voidtest() {

Toast.makeText(getApplicationContext(),"这是java代码的Test方法", Toast.LENGTH_LONG).show();

}

}

调用为:

webView.getSettings().setJavaScriptEnabled(true);

webView.addJavascriptInterface(new JavascriptInteerface(), "testObject");

按照上面的方法,在我的手机(android系统版本为4.4.2)上运行没有反应,查看log时显示如下错误:

E/Web Console﹕ Uncaught TypeError: Object [object Object] has no method 'test' at about:blank:1

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

官网对于该问题大概描述如下:

public void addJavascriptInterface (Object object, String name)

Injects the supplied Java object into this WebView. 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 accessed from JavaScript. For applications targeted to API level

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

classJsObject{@JavascriptInterfacepublicStringtoString(){return"injectedObject";}}webView.addJavascriptInterface(newJsObject(),"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 apps targeting

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.

For applications targeted to API level

所以,要解决上述问题:只需要在每个Javascript要调用的Java接口中得每个方法前加上这句@JavascriptInterface。例如我之前的代码改为

public final classJavascriptInteerface{

@JavascriptInterfacepublic voidtest() {

Toast.makeText(getApplicationContext(),"这是java代码的Test方法", Toast.LENGTH_LONG).show();

}

}

三、关于代码混淆导致JS和Java无法交互的问题

就在做好上面的所有事情后,以为就没事了,可是,上线的时候发现根本就无法交互。原因:在混淆之后注入的JAVA接口被重命名了,导致html里的Js无法匹配Java的接口名。

解决方法:(根据我“一”条目中得使用代码来说明):在混淆文件中加入如下配置

-keepclassmembers class com.test.package.TestActivity$JavascriptMethodClass { public *;}

# 以下两行为在Android4.2版本以上的手机必须加入的对注解进行处理的配置

-keepattributes *Annotation*

-keepattributes *JavascriptInterface*

四、Android和IOS共同开发的小提示

至此,该问题就得到解决。除了该问题外,在做IOS和Android同时跟同一个HTML5中得JS交互时,也会遇到一个问题,主要是向注入js对象不一样导致,这种解决方法最好是在IOS向HTML动态注入js代码;也可以在JS中判断客户端使用的设备,在此就不多做说明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值