概述
场景:Android的Webview中,javascript怎么调用java方法
Android的Webview中,javascript如何调用java方法
PS:另外推荐下面这篇文章《用注解和pojo支撑起来的轻量级REST框架--T2》
http://blog.csdn.net/nanjingjiangbiao/article/details/7680702
今天调查一个线上Bug,发现是WebView中的一小段javascript,会直接调用到后台APK的一个Java事件,最后导致java中nullpointexception。
感兴趣的是,WebView中的javascript如何调用APK中的java方法。
一个例子:
通过JS取得Android的GPS数据
第一步,WebKit的准备
首先,给与WebKit的javascript的执行许可
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
WebView wv = new WebView(this);
wv.getSettings().setJavaScriptEnabled(true);//JS利用OK
setContentView(wv);
}
然后,塞入自己的javascript拦截器JsObj jo = new JsObj(this);
wv.addJavascriptInterface(jo, "roid");
第二步,定义自己的javascript拦截器
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
JS calls Android MethodJS on Android
document.write(roid.gps("", ""));
在这个代码里面,可以用roid.gps的方法调用第二步定义的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.addJavascriptInterface(jo, "roid");
setContentView(wv);
wv.loadUrl("http://www.adamrocker.com/android/js2android.html");
}
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初期化的时候/* 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, mJavascriptInterfaces);
mJavascriptInterfaces = 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。 通过messageNameTransfer all messages to the newly created webcore thread handler.
private void [More ...] transferMessages() {
mTid = Process.myTid();
mSavedPriority = Process.getThreadPriority(mTid);
mHandler = new Handler() {
@Override
public void [More ...] handleMessage(Message msg) {
if (DebugFlags.WEB_VIEW_CORE) {
Log.v(LOGTAG, (msg.what < REQUEST_LABEL
|| msg.what
> VALID_NODE_BOUNDS ? Integer.toString(msg.what)
: HandlerDebugString[msg.what
- REQUEST_LABEL])
+ " arg1=" + msg.arg1 + " arg2=" + msg.arg2
+ " obj=" + msg.obj);
}
switch (msg.what) {
case WEBKIT_DRAW:
webkitDraw();
所以你要问我他们是怎么通信的
我只能说是线程间通信。
#以上#
1楼xiaofufu113小时前谢谢分享。
最后
以上就是英勇唇膏为你收集整理的WebView突然无法调用JAVA,Webview javascript 调用java方法JS on Android的全部内容,希望文章能够帮你解决WebView突然无法调用JAVA,Webview javascript 调用java方法JS on Android所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复