现在很多的
手机应用,都可能会直接嵌入一个
web页面。这样做的好处:一个是功能更新方便,维护起来容易,只需要维护
服务器的页面即可,不需要更新客户端;另一个是功能通用,不仅
Android可以用,
ios也可以用,symbian也可以直接用。而且WebView对
javascript的支持很强,但也没有亲身编程测试一下,所有这里举个例子说明一下如何在
javascript中调用
java中函数
1、创建一个
Android 工程 TestWebView
2、继承自 Activity
[
java]
<pre name="code" class="
java" style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; "><span style="font-size:16px;">public class TestWebView extends Activity {
private WebView mWebView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mWebView = (WebView) findViewById(R.id.htmlview);
WebSettings webSettings = mWebView.getSettings();
// 是否允许在webview中执行
javascript
webSettings.set
javaScriptEnabled(true);
// 绑定
java对象到
javaScript中,这样就能在
javaScript中调用
java对象,实现通信。
// 这种方法第一个参数就是
java对象,第二个参数表示
java对象的别名,在
javaScript中使用
mWebView.add
javascript
interface(new Demo
javaScriptInterface(), "demo");
// webview加载本地html代码,注意本地html代码必须放在工程assets目录下,然后通过
// file:///
Android_asset/demo.html访问
mWebView.loadUrl("file:///
Android_asset/demo.html");
}
public class Demo
javaScriptInterface {
public Demo
javaScriptInterface() {
}
public int mydata() {
Log.i("TEST","mydata.....");
return 0;
}
}
}</span>
<pre name="code" class="
java" style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; "><span style="font-size:16px;">public class TestWebView extends Activity {
private WebView mWebView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mWebView = (WebView) findViewById(R.id.htmlview);
WebSettings webSettings = mWebView.getSettings();
// 是否允许在webview中执行
javascript
webSettings.set
javaScriptEnabled(true);
// 绑定
java对象到
javaScript中,这样就能在
javaScript中调用
java对象,实现通信。
// 这种方法第一个参数就是
java对象,第二个参数表示
java对象的别名,在
javaScript中使用
mWebView.add
javascriptInterface(new Demo
javaScriptInterface(), "demo");
// webview加载本地html代码,注意本地html代码必须放在工程assets目录下,然后通过
// file:///
Android_asset/demo.html访问
mWebView.loadUrl("file:///
Android_asset/demo.html");
}
public class Demo
javaScriptInterface {
public Demo
javaScriptInterface() {
}
public int mydata() {
Log.i("TEST","mydata.....");
return 0;
}
}
}</span>
3、修改 main.xml 文件如下
[html]
<span style="font-size:16px;"><?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:
Android="http://schemas.
Android.com/apk/res/
Android"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
>
<WebView
Android:id="@+id/htmlview"
Android:layout_centerHorizontal="true"
Android:layout_centerVertical="true"
Android:layout_marginLeft="0px"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent" />
</RelativeLayout></span>
<span style="font-size:16px;"><?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:
Android="http://schemas.
Android.com/apk/res/
Android"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
>
<WebView
Android:id="@+id/htmlview"
Android:layout_centerHorizontal="true"
Android:layout_centerVertical="true"
Android:layout_marginLeft="0px"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent" />
</RelativeLayout></span>
4、在assets目录下,新建一个html文件:demo.html,使用
javaScript代码编写
[
javascript]
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>this is web html
<div id="output" >test</div>
<input type="submit" value="buttons"
/>
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>this is web html
<div id="output" >test</div>
<input type="submit" value="buttons"
/>
</body>
</html>
注意上面 [
javascript] view plaincopyprint?
onclick="document.getElementById('output').innerHTML=window.demo.mydata()"
onclick="document.getElementById('output').innerHTML=window.demo.mydata()"
直接调用 window.demo.mydata() 的方法
ok, 轻松就将代码写完,现在补充说明一下用到的知识点:
先看SDK API函数介绍:
public void add
javascriptInterface (Object obj, String interfaceName)
Use this function to bind an object to
javaScript so that the methods can be accessed from
javaScript.
IMPORTANT:
Using add
javascriptInterface() allows
javaScript to control your application. This can be a very useful feature or a dangerous security issue. When the HTML in the WebView is untrustworthy (for example, part or all of the HTML is provided by some person or process), then an attacker could inject HTML that will execute your code and possibly any code of the attacker's choosing.
Do not use add
javascriptInterface() unless all of the HTML in this WebView was written by you.
The
java object that is bound runs in another thread and not in the thread that it was constructed in.
Parameters
obj The class instance to bind to
javaScript, null instances are ignored.
interfaceName The name to used to expose the instance in
javaScript.
通过add
javascriptInterface(Object obj,String interfaceName)这个方法,该方法将一个
java对象绑定到一个
javascript对象中,
javascript对象名就是 interfaceName(demo),作用域是Global。这样初始化webview后,在webview加载的页面中就可以直接通过
javascript:window.demo访问到绑定的
java对象了。
再补充下在开发过程中应该注意几点:
1、
AndroidManifest.xml中必须使用许可"
Android.permission.INTERNET",否则会出Web page not available错误
2、如果访问的页面中有
javascript,则webview必须设置支持
javascript。
webview.getSettings().set
javaScriptEnabled(true);
3、如果页面中链接,如果希望点击链接继续在当前browser中响应,而不是新开
Android的系统browser中响应该链接,必须覆盖webview的WebViewClient对象。
mWebView.setWebViewClient(new WebViewClient(){
[
java]
<span style="font-size:16px;"> @Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});</span>
<span style="font-size:16px;"> @Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});</span>
4、如果不做任何处理,浏览网页,点击系统“Back”键,整个Browser会调用finish()而结束自身,如果希望浏览的网页回退而不是推出浏览器,需要在当前Activity中处理并消费掉该Back事件。
[
java]
<pre name="code" class="
java" style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; "><span style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; "></span><pre name="code" class="
java"> @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) ;; mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
<pre name="code" class="
java" style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; "><span style="font-family: Arial, Helvetica, simsun, u5b8bu4f53; "></span><pre name="code" class="
java"> @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) ;; mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
5、add
javascriptInterface方法中要绑定的
java对象及方法要运行另外的线程中,不能运行在构造他的线程中,这也是使用Handler的目的。如此上面的代码则可以修改成如下即可,利用Handler发送消息进行处理:
[
java]
<span style="color:rgb(75,78,81); line-height:25px"><span style="font-size:16px"></span></span><pre name="code" class="
java"> public int mydata() {
mHandler.post(new Runnable() {
public void run() {
Log.i("TEST", "mydata.....");
}
});
return 0;
}
摘自 andyhuabing的专栏