JSBridge連線JAVA和JS的橋樑
今天帶來github上的一個開源庫,JSBridge!
什麼是JSBridge ?
其實很好理解,是一個Java和JavaScript之間的一座橋樑。
為什麼要用JSBridge?
它提供了安全、方便的方式從js呼叫Java程式碼和呼叫js程式碼從Java。
效果圖:
可能看效果,剛開始會有點不明白。沒事,仔細看下下面的介紹,相信你會對這個庫有個深入的瞭解,其實內容不是很多!
首先引入github上的依賴庫:
app目錄下的.build檔案
dependencies {
compile 'com.github.lzyzsd.jsbridge:library:1.0.0'
}
JS呼叫原生的方法,實現JS傳參到原生,原生響應資料給JS。
JS中程式碼:
function testClick1() {
var str1 = document.getElementById("text1").value;
var str2 = document.getElementById("text2").value;
//call native method關鍵方法,呼叫原生方法
window.WebViewJavascriptBridge.callHandler(
'submitFromWeb' //原生的方法名
, {'param': str1}//帶個原生方法的引數
, function(responseData) {//響應原生回撥方法
document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData
}
);
}
原生中的方法:
//JS呼叫原生的方法,原生方法名與JS呼叫一致
webView.registerHandler("submitFromWeb", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {//data是Js傳來的資料,function方法是回撥給Js的(帶Str引數)
Log.i(TAG, "handler = submitFromWeb, data from web = " + data);//data即為JS傳來的使用者名稱
function.onCallBack("submitFromWeb exe, response data from Java");//返回給JS的資料
}
});
設定一個預設的handler,這樣Js呼叫原生的方法時不需要宣告Handler的名稱
原生方法:
webView.setDefaultHandler(new DefaultHandler());
Js方法:
function testClick() {
var str1 = document.getElementById("text1").value;
var str2 = document.getElementById("text2").value;
//send message to native
var data = "name=" + str1 + ",pass=" + str2;
window.WebViewJavascriptBridge.send(
data
, function(responseData) {
document.getElementById("show").innerHTML = "repsonseData from java, data = " + responseData
}
);
這樣Js呼叫原生的方法返回的響應資料,其實是DefaultHandler中實現的:
public class DefaultHandler implements BridgeHandler {
String TAG = "DefaultHandler";
public DefaultHandler() {
}
public void handler(String data, CallBackFunction function) {
if(function != null) {
function.onCallBack("DefaultHandler response data");
}
}
}
感覺這個方法不是特別實用,接著往下看!
原生呼叫Js中的放法:
原生方法:
@Override
public void onClick(View v) {
if (button.equals(v)) {
//原生通過callHandler方法,可以調起JS中名為functionInJs的方法
webView.callHandler("functionInJs", "data from Java", new CallBackFunction() {
@Override
public void onCallBack(String data) {
// TODO Auto-generated method stub
//data是Js的functionInJs中返回的資料
Log.i(TAG, "reponse data from js " + data);
}
});
}
}
JS中functionInJs的方法:
connectWebViewJavascriptBridge(function(bridge) {
bridge.init(function(message, responseCallback) {
console.log('JS got a message', message);
var data = {
'Javascript Responds': 'Wee!'
};
console.log('JS responding with', data);
responseCallback(data);
});
//這裡就是Js註冊的functionInJs方法,data即為原生帶來的引數
bridge.registerHandler("functionInJs", function(data, responseCallback) {
//將原生帶來的引數,顯示在show標籤位置
document.getElementById("show").innerHTML = ("data from Java: = " + data);
var responseData = "Javascript Says Right back aka!";
//呼叫responseCallback方法可以帶傳引數到原生
responseCallback(responseData);
});
})
OK,那麼上面效果預設進來的時候show標籤裡面的資料是哪裡來的呢,其實在原生的MainActivity中還有一個地方呼叫了Js中註冊的functionInJs方法
MainActicvity方法中,這裡user是原生定義的一個物件
//將User物件傳遞給JS的functionInJs方法,同樣會走到上面Js的functionInJs方法中
webView.callHandler("functionInJs", new Gson().toJson(user), new CallBackFunction() {
@Override
public void onCallBack(String data) {
}
});
再來看js裡面選擇檔案上傳的,呼叫原生的方法
js中只要宣告:
<input type="file" value="開啟檔案" />
即可,主要工作在原生的MainActivity中執行:
webView.setWebChromeClient(new WebChromeClient() {
@SuppressWarnings("unused")
public void openFileChooser(ValueCallback<Uri> uploadMsg, String AcceptType, String capture) {
this.openFileChooser(uploadMsg);
}
@SuppressWarnings("unused")
public void openFileChooser(ValueCallback<Uri> uploadMsg, String AcceptType) {
this.openFileChooser(uploadMsg);
}
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
mUploadMessage = uploadMsg;
pickFile();
}
});
pickFile()方法是原生調起本地相簿
public void pickFile() {
Intent chooserIntent = new Intent(Intent.ACTION_GET_CONTENT);
chooserIntent.setType("image/*");
startActivityForResult(chooserIntent, RESULT_CODE);
}
Intent實現的回撥函式
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == RESULT_CODE) {
if (null == mUploadMessage){
return;
}
Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData();
//這裡呼叫該方法,將原生得到的資料返回給JS
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
ps:注意,這個lib將把WebViewJavascriptBridge 物件注入視窗物件,因此,在你的js中使用webviewJavascripBridge之前,你必須確認你的WebViewJavaScriptBridge存在,如果你的webViewJavasciptBridge不存在,你可以監聽webViewJavascriptBridgeReady事件
function connectWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener(
'WebViewJavascriptBridgeReady'
, function() {
callback(WebViewJavascriptBridge)
},
false
);
}
}