做项目时候会遇到我们用WebView 打开一个web,希望这个web可以调用自己的一些方法,比如我们在进一个web页面,然后当我们点击web上的某个按钮时,希望能判断当前手机端是否已经登录,如果未登录,那么就会跳转到登录页面(登陆页面是另一个Activity)。这个时候,一个简单的做法就是在按钮动作事件的js上调用java的方法,从而起到判断是否登录,并决定是否跳转到另一个页面。
Google的WebView为我们提供了 addJavascriptInterface(Object obj, String interfaceName)方法,这个方法的第一个参数是传给Web的对象,第二个参数是该对象的对象名。
写个简单的例子
public class WebActivity extends Activity{ ProgressBar mProgressBar;
WebView mWebView;
String mUrl; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.web);
mWebView = (WebView) findViewById(R.id.web_view);
mProgressBar = (ProgressBar) findViewById(R.id.loading_progress);
doWebViewSetting();
// 加载网页
loadUrl("http://172.10.1.2:8080/test");
} private void doWebViewSetting(){
// 设置WebClient(可不要)
mWebView.setWebViewClient(new MyWebViewClient());
// 支持js(必要)
mWebView.getSettings().setJavaScriptEnabled(true);
// 添加js对象(必要)
mWebView.addJavascriptInterface(new JsOperation(this), "client");
} private void loadUrl(String url) {
mUrl = url;
mProgressBar.setVisibility(View.VISIBLE);
mWebView.loadUrl(url);
} class MyWebViewClient extends WebViewClient{
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
mProgressBar.setVisibility(View.GONE);
}
}
class JsOperation { Activity mActivity; public JsOperation(Activity activity) {
mActivity = activity;
} // 测试方法
@javascriptInterface
public void test() {
Toast.makeText(mActivity,"test",Toast.LENGTH_SHORT).show();
}
}
以上是我的WebActivity ,我这里只简单的实现的加载时进度条显示和提供对象给js。可以看出,我们提供了一个JsOperation 对象给web,然后在JsOperation 类中定义了test()方法。接下来就看看,Web方面要如何调用该方法。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>测试</title>
<script type="text/javascript">
function test(){
client.test()
} </script>
</head>
<body>
<br />
<button onclick="test()">test</button>
</body>
</html>
web的实现方式特别简单,直接调用我们提供的对象,这里要注意的是,对象名是我们之前传入的String,这里是client,直接调用它的test()方法,就能弹出一个Toast了,当然你也可以在这个方法里做其他的各种处理,也可以提供多个方法,如果你需要传入参数,那么在java上定义好形参后,js上就正常的调用方法并传入参数,如client.test(param)就可以了,没什么特别要注意的地方。
特别注意:Android的WebView存在安全漏洞,因为js调用对象是可以通过反射再调用Runtime甚至可能以web挂马形式控制主机,google也承认webView这个功能太强了,给了web很大的权利,Android 4.2 (api17)已经开始采用新的接口方法,@JavascriptInterface 代替addjavascriptInterface, 但是低版本上是不能避免。