Android中Webview使用自定义的javascript进行回调
先说为什么需要讨论这个问题。
现在很多的手机应用,都可能会直接嵌入一个web页面。这样做的好处:一个是功能更新方便,维护起来容易,只需要维护服务器的页面即可,不需要更新客户端;另一个是功能通用,不仅android可以用,ios也可以用,symbian也可以直接用。
那为什么现在很多手机应用并不做成web方式的呢?原因很多。一个是现阶段web方式展现能力相对较弱,如果对于应用的美观程度要求比较高,就无法使用web方式;一个是web方式速度相对较慢,用户体验会受一些影响;一个是现阶段流量还是相对宝贵,web方式流量相对较大;还有一个就是有一些功能无法使用web方式实现(关于这一点,现在又很多开源的项目可以实现手机的一些硬件功能,比如拍照啊,获取通讯录啊,都是可以的,感兴趣的可以搜索一下phoneGap。但是从现有的反馈来看,速度较慢,体验较差)。
基于以上的原因,现在很多项目会把一部分功能做成web方式的,一部分功能用其它控件来写。这就需要web页面与其它控件做一些交互。如何交互呢,就是利用自定义的javascript。
下面虚拟一个场景。
现在有一个功能,展现当前用户的好友列表,好友列表页是web方式的,点击某好友的头像以后,进入该好友的详情页面,而这个页面呢,由于某些原因,没做成web方式的。
假设好友列表页是UserListActivity,包含一个webview。好友详情页面是UserDetailActivity,包含很多控件和业务逻辑。
我们以id来唯一标示用户。好友列表页中,点击每一个好友头像,都会调用:
onclick="javascript:android.user('1')"
类似这样的js语句。因本文主要介绍android,而不是web开发内容,所以具体不再详述,熟悉web开发的同学很容易理解。
我们现在需要做的,就是显示用户列表页面,然后在用户点击头像以后,响应具体的js请求,跳到该好友详细页面。
下面看看大概的实现方法。
默认情况下,在WebView中是不能使用javascript的。可以通过下面的代码:
WebViewmyWebView=(WebView)findViewById(R.id.webview);
WebSettingswebSettings=myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
使javascript功能可用。这部分代码都放在UserListActivity中的onCreate()方法里。
然后是注册JS接口。先看看webview的一个方法。
publicvoidaddJavascriptInterface(Objectobj,StringinterfaceName)
Since:APILevel1
UsethisfunctiontobindanobjecttoJavaScriptsothatthemethodscanbeaccessedfromJavaScript.
IMPORTANT:
·UsingaddJavascriptInterface()allowsJavaScripttocontrolyourapplication.Thiscanbeaveryusefulfeatureoradangeroussecurityissue.WhentheHTMLintheWebViewisuntrustworthy(forexample,partoralloftheHTMLisprovidedbysomepersonorprocess),thenanattackercouldinjectHTMLthatwillexecuteyourcodeandpossiblyanycodeoftheattacker'schoosing.
DonotuseaddJavascriptInterface()unlessalloftheHTMLinthisWebViewwaswrittenbyyou.
·TheJavaobjectthatisboundrunsinanotherthreadandnotinthethreadthatitwasconstructedin.
Parameters
obj
TheclassinstancetobindtoJavaScript,nullinstancesareignored.
interfaceName
ThenametousedtoexposetheinstanceinJavaScript.
我们在UserListActivity类的onCreate()方法中增加如下语句:
mWebView.addJavascriptInterface(this,"android");
在UserListActivity类中增加如下方法:
publicvoiduser(Stringid){
//获取id,跳转activity。
}
这样当页面调用onclick="javascript:android.user('1')"语句的时候,就可以映射到UserListActivity对象的user()方法了。
这里user方法有一个参数,是要对应js语句的user(‘1’)。
下面附上所有代码。
Android部分的代码:
packagecom.arui.framework.android.js;
importandroid.app.Activity;
importandroid.content.Intent;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.webkit.WebSettings;
importandroid.webkit.WebView;
importcom.arui.framework.R;
importcom.arui.framework.android.js.UserDetailActivity;
publicclassUserListActivityextendsActivity{
privateWebViewmWebView;
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.id.userlist);
mWebView=(WebView)findViewById(R.id.mywebview);
WebSettingswebSetting=mWebView.getSettings();
//设置js可用
webSetting.setJavaScriptEnabled(true);
//添加js调用接口
mWebView.addJavascriptInterface(this,"android");
//载入具体的web地址
mWebView.loadUrl("http://blog.csdn.net/arui319");
mWebView.setVisibility(View.VISIBLE);
mWebView.requestFocus();
}
publicvoiduser(Stringid){
//跳转activity
Intentintent=newIntent(this,UserDetailActivity.class);
intent.putExtra("id",id);
startActivity(intent);
}
}
资源文件:
<?xmlversion="1.0"encoding="utf-8"?><linearlayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><webviewandroid:id="@+id/mywebview"android:layout_width="fill_parent"android:layout_height="fill_parent"android:visibility="gone"></webview></linearlayout>
Web页面的局部代码:
<imgsrc="%E2%80%A6%E2%80%A6">
---------------------------------------------------------------------------
GL(arui319)
http://blog.csdn.net/arui319