博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
webview和js交互
阅读量:6137 次
发布时间:2019-06-21

本文共 4986 字,大约阅读时间需要 16 分钟。

今天主要总结两点:一是使用Js去调用客户端公有方法,二是从客户端调用Js中的方法

一、JS调用客户端公有方法

上例子:(PS:不会写JS,就网上找了一段js代码)

新建项目,在项目的assets文件夹下创建一个test.html:

[HTML] 
纯文本查看 
复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<
body
>
<
a
>Web与Js交互:点击我,来调用客户端的show方法吧</
a
>
<
script
>
  
function funFromjs(){
    
document.getElementById("helloweb").innerHTML="我是JS里的方法";
  
}
  
var aTag = document.getElementsByTagName('a')[0];
  
aTag.addEventListener('click', function(){
    
//调用android本地方法
    
AppFunction.show("Js调用show()方法成功!");
    
return false;
  
}, false);
  
</
script
>
<
p
></
p
>
<
div
id
=
"helloweb"
>
</
div
>
</
body
>

这段代码有两个重点,一是funFromjs()方法,该方法是js里提供给客户端去调用的方法。二是AppFunction.show();show()方法是客户端提供给js去调用的方法,AppFunction是定义的接口名。底下是客户端的实现:

[Java] 
纯文本查看 
复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package
com.aliao.web;
import
android.annotation.SuppressLint;
import
android.support.v7.app.ActionBarActivity;
import
android.os.Bundle;
import
android.webkit.JavascriptInterface;
import
android.webkit.WebView;
import
android.widget.Toast;
public
class
MainActivity
extends
ActionBarActivity {
  
private
WebView mWebView;
  
@Override
  
protected
void
onCreate(Bundle savedInstanceState) {
    
super
.onCreate(savedInstanceState);
    
setContentView(R.layout.activity_main);
    
initViews();
  
}
  
private
void
initViews() {
    
String url =
""
;
    
mWebView = (WebView) findViewById(R.id.webview);
    
mWebView.getSettings().setJavaScriptEnabled(
true
);
//支持js
    
mWebView.addJavascriptInterface(
this
,
"AppFunction"
);
    
mWebView.loadUrl(url);
  
}
  
@JavascriptInterface
  
public
void
show(String msg){
    
Toast.makeText(
this
, msg, Toast.LENGTH_SHORT).show();
  
}
}

这里需要注意的是,在Android4.2.2及之后的版本只有带有 JavascriptInterface 注释的public方法才能够被js访问。所以要在show()方法前加:@JavascriptInterface

具体查看: Webview addJavascriptInterface()(http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object,%20java.lang.String))

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_BEANor 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:

[Java] 
纯文本查看 
复制代码
1
2
3
4
5
6
class
JsObject {[/backcolor] 
@JavascriptInterface
  
public
String toString() {
return
"injectedObject"
; }
}
webView.addJavascriptInterface(
new
JsObject(),
"injectedObject"
);
webView.loadData(
""
,
"text/html"
,
null
);
webView.loadUrl(
"javascript:alert(injectedObject.toString())"
);
这段是说,注入提供的java对象到WebView中。该对象以接口名的方式被注入到Javascript的上下文环境中。这样就可以在JavaScript中去访问该对象的方法。对于APl Level在4.2及以上的应用,只有带有 
JavascriptInterface 注释的的公有方法可以被JavaScript访问。对于Api Level在4.1及以下的应用,所有的公有方法都可以被访问(包括继承的方法),参见下面的重要的安全注意的影响。(系统版本在4.2以下要考虑的安全问题先mark下这个blog: 
Android WebView的Js对象注入漏洞解决方案http://blog.csdn.net/leehong2005/article/details/11808557

这里我把当前类的对象注入到webview中,命名为AppFunction,这样在JavaScript里就可以通过AppFunction直接访问MainActivity中定义的供js调用方法。

[Java] 
纯文本查看 
复制代码
1
mWebView.addJavascriptInterface(
this
,
"AppFunction"
);

也可以自定义一个类,例如上例中的

[Java] 
纯文本查看 
复制代码
1
webView.addJavascriptInterface(
new
JsObject(),
"injectedObject"
);

定义一个JsObject类,该类里定义了提供给Js调用的方法,将该对象命名为injectedOnject,即接口名注入到js中。

运行后的结果:

二、JS调用客户端公有方法

前面写过的test.html里已经提供了一个供Android客户端调用的方法funFromjs(),那客户端的代码要怎么写?

在MainActivity的布局文件中添加一个按钮,点击该按钮后,调用js中的funFromjs方法:

[Java] 
纯文本查看 
复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package
com.aliao.web;
import
android.support.v7.app.ActionBarActivity;
import
android.os.Bundle;
import
android.view.View;
import
android.webkit.JavascriptInterface;
import
android.webkit.WebView;
import
android.widget.Button;
import
android.widget.Toast;
public
class
MainActivity
extends
ActionBarActivity {
  
private
WebView mWebView;
  
private
Button mBtnCallJsFun;
  
@Override
  
protected
void
onCreate(Bundle savedInstanceState) {
    
super
.onCreate(savedInstanceState);
    
setContentView(R.layout.activity_main);
    
initViews();
  
}
  
private
void
initViews() {
    
String url =
""
;
    
mWebView = (WebView) findViewById(R.id.webview);
    
mWebView.getSettings().setJavaScriptEnabled(
true
);
//支持js
    
mWebView.addJavascriptInterface(
this
,
"AppFunction"
);
    
mWebView.loadUrl(url);
    
mBtnCallJsFun = (Button) findViewById(R.id.btn_call_js_fun);
    
mBtnCallJsFun.setOnClickListener(
new
View.OnClickListener() {
      
@Override
      
public
void
onClick(View v) {
        
mWebView.loadUrl(
"javascript:funFromjs()"
);
      
}
    
});
  
}
  
@JavascriptInterface
  
public
void
show(String msg){
    
Toast.makeText(
this
, msg, Toast.LENGTH_SHORT).show();
  
}
}

运行结果:

你可能感兴趣的文章
《SAS 统计分析与应用从入门到精通(第二版)》一1.4 SAS系统的文件管理
查看>>
《众妙之门——网页设计专业之道》——2.4 总结
查看>>
MySQL sql_mode 说明(及处理一起 sql_mode 引发的问题)
查看>>
Java 注解详解 (annotation)
查看>>
鹰眼跟踪、限流降级,EDAS的微服务解决之道
查看>>
秘籍:程序猿该如何实力撩妹
查看>>
网络编程socket基本API详解
查看>>
API接口设计 OAuth2.0认证
查看>>
Mysql5.6的1755错误解决办法
查看>>
在命令行中运行“mvn compile”因为中文报错
查看>>
Docker的技术不再局限于测试和开发
查看>>
技术干货:工欲善其事,必先利其器 阿里云数据库系列谈之一
查看>>
禁用ViewState
查看>>
深入理解Java HashMap实现原理
查看>>
阿里云备案获取服务号
查看>>
深入理解Python中的__builtin__和__builtins__
查看>>
YII AJAX registerScript
查看>>
ARC forbids explicit message send of 'retainCount'
查看>>
redis单机安装
查看>>
golang内存分配
查看>>