Android的Webview中,javascript如何调用java方法
今天调查一个线上Bug,发现是WebView中的一小段javascript,会直接调用到后台APK的一个Java事件,最后导致java中nullpointexception。
感兴趣的是,WebView中的javascript如何调用APK中的java方法。
一个例子:
通过JS取得Android的GPS数据
第一步,WebKit的准备
首先,给与WebKit的javascript的执行许可
[java]
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
WebView wv = new WebView(this);
wv.getSettings().setJavaScriptEnabled(true);//JS利用OK
setContentView(wv);
}
然后,塞入自己的javascript易做图
[java]
JsObj jo = new JsObj(this);
wv.addJavascriptInte易做图ce(jo, "roid");
第二步,定义自己的javascript易做图
[java]
class JsObj {
private Context con;
public JsObj(Context con) {
this.con = con;
}
public String gps(String top, String end) {
LocationManager locman = (LocationManager)
con.getSystemService(Context.LOCATION_SERVICE);
Location loc = locman.getCurrentLocation("gps");
int lat = (int) (loc.getLatitude() * 1000000);
int lon = (int) (loc.getLongitude() * 1000000);
return top + "緯度:" + lat + ", 経度: " + lon + end;
}
}
第三步,定义一个可运行的html
[html]
<html>
<head><title>JS calls Android Method</title></head>
<body>
<h1>JS on Android</h1>
<script type="text/javascript">
document.write(roid.gps("<i>", "</i>"));
</script>
</body>
</html>
在这个代码里面,可以用roid.gps的方法调用第二步定义的java函数
最后,全部的代码
[java]
package com.adamrocker.android.web;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.webkit.WebView;
public class WebkitTest extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
WebView wv = new WebView(this);
wv.getSettings().setJavaScriptEnabled(true);
JsObj jo = new JsObj(this);
wv.addJavascriptInte易做图ce(jo, "roid");
setContentView(wv);
wv.loadUrl("www.zzzyk.com");
}
class JsObj {
private Context con;
public JsObj(Context con) {
this.con = con;
}
public String gps(String top, String end) {
LocationManager locman = (LocationManager) con
.getSystemService(Context.LOCATION_SERVICE);
Location loc = locman.getCurrentLocation("gps");
int lat = (int) (loc.getLatitude() * 1000000);
int lon = (int) (loc.getLongitude() * 1000000);
return top + "緯度:" + lat + ", 経度: " + lon + end;
}
}
}
未完
我还想知道为什么,在webview里面定义一个JSObject,就可以连接javascript和后台函数
他们之间是如何通信的?
我稍微调查了一下WebView的底层代码,webview初期化的时候
[java]
/* Initialize private data within the WebCore thread.
*/
private void [More ...] initialize() {
/* Initialize our private BrowserFrame class to handle all
* frame-related functions. We need to create a new view which
* in turn creates a C level FrameView and attaches it to the frame.
*/
mBrowserFrame = new BrowserFrame(mContext, this, mCallbackProxy,
mSettings, mJavascriptInte易做图ces);
mJavascriptInte易做图ces = null;
// Sync the native settings and also create the WebCore thread handler.
mSettings.syncSettingsAndCreateHandler(mBrowserFrame);
// Create the handler and transfer messages for the IconDatabase
WebIconDatabase.getInstance().createHandler();
// Create the handler for WebStorage
WebStorage.getInstance().createHandler();
// Create the handler for GeolocationPermissions.
GeolocationPermissions.getInstance().createHandler();
// The transferMessages call will transfer all pending messages to the
// WebCore thread handler.
mEventHub.transferMessages();
// Send a message back to WebView to tell it that we have set up the
// WebCore thread.
if (mWebView != null) {
Message.obtain(mWebView.mPrivateHandler,
WebView.WEBCORE_INITIALIZED_MSG_ID,
mNativeClass, 0).sendToTarget();
}
}
生成了显示用对象
mBrowserFrame
而此对象的所有操作事件,都会被
mEventHub截获
而mEventHub会将请求发送给真正需要处理的MessageStub。 通过messageName
[java]
Transfer all messages to the newly created webcore thread handler.
private void [More ...] transferMessages() {
mTid = Process.myTid();
mSavedPriority = Process.getThre
补充:移动开发 , Android ,