根据IOS marcuswestin/WebViewJavascriptBridge 编写而来的JavascriptBridge。
相比同类库的优点:
- 和IOS marcuswestin/WebViewJavascriptBridge 一样的使用方法,可共用一套JS代码。
- 同时也在此之上做了加强,参考了Cordova源码的模块管理,方便把各种不同的原生功能封装成独立的模块并统一管理。具体请看下面的 模块管理功能一栏。
规定JS和Java之间用标准JSON格式字符串交互,JS传给Java的数据会封装成 org.json.JSONObject。
(An Android bridge for sending messages between Java and JavaScript in WebViews. Based on IOS marcuswestin/WebViewJavascriptBridge.)
repositories {
jcenter()
}
compile 'com.luffyjet:webviewjavascriptbridge:1.0'See the app/ folder.
- Init WebViewJavaScriptBridge
WebSettingssettings = webView.getSettings();
settings.setJavaScriptEnabled(true);//很关键WebViewJavaScriptBridgemBridge = WebViewJavaScriptBridge.bridgeForWebView(this, webView);
mBridge.setWebViewDelegate(newMyWebViewClient());//设置WebViewClientwebView.setWebChromeClient(newMyChromeClient());//设置ChromeClient- Register a handler in Java, and call a JS handler:
//注册一个 处理 js端发来消息的 handlermBridge.registerHandler("abs", newWebViewJavaScriptBridgeBase.WVJBHandler() {
@Overridepublicvoidhandle(JSONObjectdata, WebViewJavaScriptBridgeBase.WVJBResponseCallbackresponseCallback) {
Log.d(TAG, "from JS req: " + data.toString());
responseCallback.callback(newJSResult("i like milk from native").toJson());
}
});
mBridge.callHandler("NativeCallJS", model.toJSON(), newWebViewJavaScriptBridgeBase.WVJBResponseCallback() {
@Overridepublicvoidcallback(StringresponseData) {
Log.d(TAG, "JS responded:" + responseData);
Toast.makeText(MainActivity.this, "JS responded:" + responseData , Toast.LENGTH_SHORT).show();
}
});
- Copy and paste
setupWebViewJavascriptBridgeinto your JS:
functionsetupWebViewJavascriptBridge(callback){if(window.WebViewJavascriptBridge){returncallback(WebViewJavascriptBridge);}if(window.WVJBCallbacks){returnwindow.WVJBCallbacks.push(callback);}window.WVJBCallbacks=[callback];varWVJBIframe=document.createElement('iframe');WVJBIframe.style.display='none';//这里最新IOS版是 https的scheme,真实环境下 需要判断iOS和Android,做下区分。WVJBIframe.src='wvjbscheme://__BRIDGE_LOADED__';document.documentElement.appendChild(WVJBIframe);setTimeout(function(){document.documentElement.removeChild(WVJBIframe)},0);}- Finally, call
setupWebViewJavascriptBridgeand then use the bridge to register handlers and call Java handlers:
setupWebViewJavascriptBridge(function(bridge){/* Initialize your app here */bridge.registerHandler('NativeCallJS',function(data,responseCallback){varresponseData={'Javascript Says': 'Right back atcha!'};log('Native call JS with ',data);responseCallback(responseData);});vardoc=document;varreadyEvent=doc.createEvent('Events');readyEvent.initEvent('WebViewJavascriptBridgeReady');readyEvent.bridge=WebViewJavascriptBridge;doc.dispatchEvent(readyEvent);});可以和Cordova一样进行模块管理,同一种类型的消息(handler name相同)都由一个模块处理。 模块类需要继承 RequestHandler ,包含WebView的Activity要实现 BridgeInterface 接口。插件类由XML文件进行配置,请在项目中新建 res/xml/wjbconfig.xml 文件。
<?xmlversion="1.0" encoding="utf-8"?><widget> <feature name="chooseImage"> <param name="android-package" value="com.luffyjet.jsbridgeexample.handlers.ImageChooseHandler"/> <param name="onload" value="true"/> </feature> <feature name="deviceInfo"> <param name="android-package" value="com.luffyjet.jsbridgeexample.handlers.DeviceInfoHandler"/> <param name="onload" value="true"/> </feature></widget>//一个简单的选图模块示例public class ImageChooseHandler extends RequestHandler { private static final String TAG = "ImageChooseHandler"; private static final int REQUEST_CODE_IMAGES = 100; private WebViewJavaScriptBridgeBase.WVJBResponseCallback mResponseCallback; @Override public void handle(JSONObject data, WebViewJavaScriptBridgeBase.WVJBResponseCallback responseCallback) { mResponseCallback = responseCallback; ... mBridgeInterface.startActivityForResult(this, Intent.createChooser(i, "选取图片"), REQUEST_CODE_IMAGES); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_IMAGES) { try { ... mResponseCallback.callback(result.toJSON()); } catch (Exception e) { e.printStackTrace(); } } }}// 包含webview 的 WebActivitypublic class WebActivity extends AppCompatActivity implements BridgeInterface{ RequestHandler mRequestHandler; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (null != mRequestHandler) { RequestHandler callback = mRequestHandler; mRequestHandler = null; callback.onActivityResult(requestCode, resultCode, data); return; } //other code } @Override public void startActivityForResult(RequestHandler command, Intent intent, int requestCode) { setActivityResultCallback(command); startActivityForResult(intent, requestCode); } @Override public void setActivityResultCallback(RequestHandler plugin) { mRequestHandler = plugin; } @Override public Activity getActivity() { return this; } @Override public ExecutorService getThreadPool() { return Executors.newCachedThreadPool(new ThreadFactory() { @Override public Thread newThread(final Runnable r) { return new Thread(new Runnable() { @Override public void run() { android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); r.run(); } },"Test");
}
});
}
}一个功能模块对应一个feature,feature name就是handle name。 onload属性为true代表模块(插件)会在webview初始化时一同初始化,false则是在需要该模块(插件)的时候通过反射加载。
具体使用方法请查看 app/ 目录下的示例代码。
marcuswestin/WebViewJavascriptBridge & lzyzsd/JsBridge & cordova-android
See the LICENSE file for license rights and limitations.