android 中java和javascript交互

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

本文参考了该博文:http://blog.csdn.net/zgjxwl/article/details/9627685



一、WebView中Java与javascript交互

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

public final class JavascriptInteerface{
        @JavascriptInterface
        public void test(String teststr) {
            Toast.makeText(getApplicationContext(), teststr, Toast.LENGTH_LONG).show();
        }

        @JavascriptInterface
        public void test1() {       // 调用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 ="<HTML><HEAD><script type=\"text/javascript\">function testJavaCall(str){alert(str);};</script></HEAD><BODY><H1>TEST1</H1></BODY><BR /><INPUT type=\"button\" value=\"js调用java\" onclick=\"window.testObject.test(‘这是js掉java的Test方法‘)\" /><INPUT type=\"button\" value=\"java调js\" onclick=\"window.testObject.test1()\" /></HTML>";

// 如果是网页,直接用loadUrl(url)方法
webView.loadDataWithBaseURL(null, data, "text/html", "utf-8", null);

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

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

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

public final class JavascriptInteerface{
        public void test() {
            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)

Added in API level 1

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 JELLY_BEAN_MR1 and above, only public methods that are annotated with JavascriptInterface can be accessed from JavaScript. For applications targeted to API level JELLY_BEAN or below, all public methods (including the inherited ones) can be accessed, see the important security note below for implications.

Note that injected objects will not appear in JavaScript until the 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 apps targeting JELLY_BEAN or earlier. Apps that target a version later than JELLY_BEAN are still vulnerable if the app runs on a device running Android earlier than 4.2. The most secure way to use this method is to target JELLY_BEAN_MR1 and to ensure the method is called only when running on Android 4.2 or later. With these older versions, 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.
  • For applications targeted to API level LOLLIPOP and above, methods of injected Java objects are enumerable from JavaScript.


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

public final class JavascriptInteerface{
        @JavascriptInterface
        public void test() {
            Toast.makeText(getApplicationContext(), "这是java代码的Test方法", Toast.LENGTH_LONG).show();
        }
}

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

时间: 2024-10-11 00:44:48

android 中java和javascript交互的相关文章

Android中Java和JavaScript交互

Android提供了一个很强大的WebView控件用来处理Web网页,而在网页中,JavaScript又是一个很举足轻重的脚本.本文将介绍如何实现Java代码和Javascript代码的相互调用. 如何实现 实现Java和js交互十分便捷.通常只需要以下几步. WebView开启JavaScript脚本执行 WebView设置供JavaScript调用的交互接口. 客户端和网页端编写调用对方的代码. 本例代码 为了便于讲解,先贴出全部代码 Java代码 package com.example.j

Android 中Java和JavaScript交互入门

如何实现JavaScript 和java 交互 实现Java和js交互十分便捷.通常只需要以下几步. WebView开启JavaScript脚本执行 WebView设置供JavaScript调用的交互接口. 客户端和网页端编写调用对方的代码. #直接看示例代码: java代码如下: package com.ccb.javascript; import java.net.URISyntaxException; import android.annotation.SuppressLint; impo

Android WebView Java和JavaScript交互

Java调用JavaScript mWebView.loadUrl("javascript:toast()"); js: <script language="javascript> <!--提供给android的java代码调用--> function toast(){ alert("fdsaf") } JavaScript调用Java WebView提供了一个名为WebSetting的工具类来实现让WebView中的JavaScr

Android中Java与JavaScript之间交互(转)

Android代码: package com.fyfeng.testjavascript; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.util.Log; import android.webkit.WebView; import androi

IOS中UIWebView和JavaScript交互(转自http://blog.2jun.net/2012/11/02/webviewandjs/)

IOS中UIWebView和JavaScript交互 当程序中使用到UIWebView控件的时候,难免会遇到需要与页面进行交互的情况.这种情况在android平台下比较容易处理,android平台下WebView控件的addJavascriptInterface()方法可以很轻松的完成交互,而IOS上就稍复杂一些. 页面与客户端的交互是通过JS来完成的,通常情况下与JS的交互可以分为两种:客户端传递给JS一些数据和JS向客户端请求一些本地操作.下面分别对这两种情况进行处理. JS向客户端请求本地

WebView上实现Java与JavaScript交互

在安卓开发上,考虑到开发效率和界面更新,有时使用WebView结合web页面技术,可以快速迭代地开发移动应用.WebView加载资源的速度并不慢,但是如果资源多了,就很慢.图片.css.js.html这些资源每个大概需要10-200ms,一般都是30ms以内就行了.但是,WebView是等全部资源加载完成才开始渲染的,所以最后用原生js来写,别用太多jQuery之类的框架,以改善用户体验. 在混合开发中,有时会用到安卓原生SDK,如调用相机.查看相册.录音等,这就需要web页面中的JavaScr

Android中Java反射技术的使用示例

import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import android.os.Bundle; import android.app.Activity; /** * Demo描述: * Android中Java反射技术的使用示例 * 在Java中描述字节码文件(xxx.class)的类叫Class * 反射的过程可视为剖析Class的过

深入分析:Android中app之间的交互

在我们开发Android App应用的时候,有些需求需要我们启动其他的App来处理一些逻辑,例如我们需要根据一个地址来调用系统或者相关的地图Map App,这样我们不用在自己的App中编写相应的功能,而是通过Intent来发送一些请求,调用相关的应用来处理这些请求.并且我们称这种Intent为隐式的Intent:这种隐式的Intent是相对于显式的Intent来讲的.显式的Intent我们都比较熟悉,显式的Intent常常需要声明类的名称,而隐式的Intent我们需要声明一个Action,我们A

深入分析:Android中app之间的交互(二,使用ComponentName)

在前一篇相关主题的博文中我们了解了如何使用Action来启动当前应用之外的Activity处理我们的业务逻辑,在本篇笔记中我在简单介绍一下使用ComponentName来与当前应用之外的应用进行交互. 在介绍Component之前,我们首先来了解ComponentName这个类:ComponentName与Intent同位于android.content包下,我们从Android官方文档中可以看到,这个类主要用来定义可见一个应用程序组件,例如:Activity,Service,Broadcast