Android和js的混合開發(fā)

一、js和Android調(diào)用的前提

在講js和Android的互調(diào)之前,我們要先設(shè)置好webview的一些基本配置

WebSettings settings = mWebView.getSettings();

settings.setJavaScriptEnabled(true);

當(dāng)然,我們還可以設(shè)置webview的客戶端,并且重寫其方法(方法有好多,以下只重寫了兩個,大家可根據(jù)自己的需求去重寫)

//設(shè)置默認的web瀏覽器

mWebView.setWebViewClient(new WebViewClient(){

//頁面開始加載的時候調(diào)用

@Override

public void onPageFinished(WebView view, String url) {

super.onPageFinished(view, url);

//網(wǎng)頁加載完后調(diào)用

try {

JSONObject json = new JSONObject();

json.put("name", "android");

json.put("message", "你好,我是安卓,加個好友唄!");

//調(diào)用js方法:webview.loadUrl(javascript:方法名(參數(shù)));

mWebView.loadUrl("javascript:showMsg("+ json.toString()+")");

} catch (JSONException e) {

e.printStackTrace();

}

}

//頁面加載結(jié)束的時候調(diào)用

@Override

public void onPageStarted(WebView view, String url, Bitmap favicon) {

super.onPageStarted(view, url, favicon);

}

});

//設(shè)置chrome瀏覽器

mWebView.setWebChromeClient(new WebChromeClient(){

@Override

public void onProgressChanged(WebView view, int newProgress) {

super.onProgressChanged(view, newProgress);

}

@Override

public void onReceivedTitle(WebView view, String title) {

super.onReceivedTitle(view, title);

}

});

*最后,可不能忘記加載地址

mWebView.loadUrl(url);

二、下面進入正文,說說js和Android的調(diào)用的三種方法

1. Android調(diào)用js

2. js調(diào)用Android

3. js使用callback調(diào)用Android,基礎(chǔ)第二種方式的升級

1、Android調(diào)用js

webview調(diào)用js的基本格式為:

webview.loadUrl(javascript:方法名(參數(shù)))

相信看到這段代碼,大家都覺得很簡單吧!對,就是那么簡單!

如果是無參,就不要寫參數(shù);

如果參數(shù)是json數(shù)據(jù),必須轉(zhuǎn)換成String在傳入

webview調(diào)用js中有返回值的方法

Android4.4之前,并沒有提供直接調(diào)用js函數(shù)并獲取值的方法,所以在此之前,常用的思路就是Androida調(diào)用js方法,js方法執(zhí)行完畢,再次調(diào)用Android代碼將值返回

1.1. java調(diào)用js(和上面上一樣的)

webview.loadUrl(javascript:方法名(參數(shù)))

2.1. js函數(shù)處理,并將結(jié)果通過java方法返回

function sumToJava(num1,num2) {

window.control.onSumResult(num1+num2)

}

3. java在回調(diào)方法中獲取js函數(shù)的返回值

@JavascriptInterface

public void onSumResult(int result) {

//邏輯處理

}

4.4之后,使用evaluateJavaScript就可以調(diào)用并獲取到j(luò)s方法中的返回值

1.1. js中的函數(shù)

function getMsg() {

return 5;

}

2.1. java代碼,用evaluatejavascript方法

//第一個參數(shù)為js中的方法名

mWebView.evaluateJavascript("getMsg()", new ValueCallback() {

@Override

public void onReceiveValue(String value) {

Toast.makeText(CallJsActivity.this,value,Toast.LENGTH_SHORT).show();

}

});

注意:第二種方法返回結(jié)果限定了為String,如果是簡單類型的數(shù)據(jù)可以轉(zhuǎn)換成String在返回,如果是復(fù)雜的數(shù)據(jù)類型,建議以字符串形式的json返回;evaluateJavascript方法必須在ui線程調(diào)用,因此onReceiveValue也執(zhí)行在主線程中

二、js調(diào)Android

js調(diào)用Android方法之前,我們需要設(shè)置一個js和Android之間的橋梁

JavaScriptMethod js = new JavaScriptMethod(this);

//設(shè)置js和Android之間的通信橋梁

//第一個參數(shù)是對象,第二個參數(shù)是第一個參數(shù)的別名(對象的映射字符串)

mWebView.addJavascriptInterface(js,"jsInterface");

創(chuàng)建一個JavaScriptMethod類,類中創(chuàng)建一個js需要調(diào)用的方法,方法上必須添加注解(4.2開始強制要求的,為了安全性考慮)

public class JavaScriptMethod {

private Context mContext;

public JavaScriptMethod(Context context) {

mContext = context;

}

@JavascriptInterface

public void showToast() {

Toast.makeText(mContext,"js調(diào)用Android中的方法",Toast.LENGTH_SHORT).show();

}

}

在js中調(diào)用showToast()方法,window.別名(Android中對象的映射字符串).方法名 ——jAndroid中必須添加這句代碼:mWebView.addJavascriptInterface(js,"jsInterface");

$("#btn1").click(function() {

window.jsInterface.showToast();

})

三、js調(diào)用Android callback

先舉個例子,假設(shè)頁面是用html5實現(xiàn),頁面上要使用一筆數(shù)據(jù),需要通過Android連網(wǎng)獲取后返回過來,請用代碼實現(xiàn)這個需求?(假設(shè),設(shè)置好了webview的配置)

首先,Android中代碼如下

//獲取酒店詳情頁數(shù)據(jù)

@JavascriptInterface

public void getHotelData(){

Toast.makeText(mContext, "android接受到j(luò)s:"+json, Toast.LENGTH_SHORT).show();

try {

JSONObject backJson = new JSONObject();

backJson.put("hotel_name", "8天連鎖酒店");

backJson.put("hotel_price", "88");

backJson.put("hotel_phone", "0755-888888888");

invokeJsMethod("hao", backJson.toString());

} catch (JSONException e) {

e.printStackTrace();

}

}

/**

* 統(tǒng)一管理android調(diào)用js:android調(diào)用js必須在主線程

* @param json

*/

private void invokeJsMethod(final String callback, final String json) {

mHandler.post(new Runnable() {

@Override

public void run() {

//數(shù)據(jù)返回給js,調(diào)用js方法

mWebView.loadUrl("javascript:"+callback+"("+json+")");

}

});

}

private Handler mHandler = new Handler();

HTML5中,代碼如下

$("#btn2").on("click", function(){

//1.js先調(diào)用android

window.jsInterface.getHotelData();

});

function hao(json){

alert("js接受到酒店數(shù)據(jù):" + JSON.stringify(json));

};

上訴方法雖然能夠?qū)崿F(xiàn)需求,但是invokeJsMethod("hao", backJson.toString())調(diào)用js中的方法名是固定的,耦合性高,一旦出了問題,到底是Android端方法名寫錯了?還是前段的妹子報復(fù)Android端的哥們故意改了方法名?這就不知道了。所以為了解決這個問題,就有了下面要將的內(nèi)容了---callback

在html5代碼中,將Android需要調(diào)用js中的方法名封裝成json數(shù)據(jù)傳遞給Android的方法

$("#btn2").on("click", function(){

var json={"callback":"hao"};

//1.js先調(diào)用android

window.jsInterface.getHotelData(JSON.stringify(json));

});

function hao(json){

alert("js接受到酒店數(shù)據(jù):" + JSON.stringify(json));

};

在Android的getHotelData方法中,只需要將json數(shù)據(jù)中的方法名解析出來,傳遞給接下來要調(diào)用js的代碼中

//獲取酒店詳情頁數(shù)據(jù)

@JavascriptInterface

public void getHotelData(String json){

try {

//通過傳過來的json數(shù)據(jù)解析獲取方法名

JSONObject jsonObject = new JSONObject(json);

String callback = jsonObject.optString("callback");

JSONObject backJson = new JSONObject();

backJson.put("hotel_name", "8天連鎖酒店");

backJson.put("hotel_price", "88");

backJson.put("hotel_phone", "0755-888888888");

invokeJsMethod(callback, backJson.toString());

} catch (JSONException e) {

e.printStackTrace();

}

....(其他與上面代碼一樣)

上訴第三種方式是比較重要的方式,大家需要記??;另外,第三步的代碼只是大致的代碼,還有一些基礎(chǔ)的配置在前面兩步已經(jīng)講過,這里就不再累贅了!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容