Android調用Js
- loadUrl()
通過WebView的loadUrl()方法調用Js方法。
mWebView.loadUrl("javascript:callJsDefault()");
//在android調用js有參的函數的時候參數要加單引號
String param = "\'來自Android的參數\'";
mWebView.loadUrl(String.format("javascript:callJsWithParams(%s)", param));
- evaluateJavascript()
通過WebView的evaluateJavascript()方法調用Js方法,此方法可以獲得Js方法執行後的返回值。
mWebView.evaluateJavascript("javascript:callJsWithReturn(2,3)",
value -> Toast.makeText(MainActivity.this, "Js的計算結果爲:" + value, Toast.LENGTH_SHORT).show());
Js調用Android
- addJavascriptInterface()
創建一個類通過WebView的addJavascriptInterface()方法提供給Js使用,Js通過它調用我們在Android中寫好的方法。
public class JsCallAndroid {
private Context mContext;
public JsCallAndroid(Context context) {
mContext = context;
}
//供Js調用的方法要加JavascriptInterface註解
@JavascriptInterface
public void hello(String msg){
Toast.makeText(mContext,msg,Toast.LENGTH_SHORT).show();
}
/*...*/
}
//"android"爲Js中調用對象的名稱
mWebView.addJavascriptInterface(new JsCallAndroid(this), "android");
Js中調用
function callAndroid(){
// 由於對象映射,所以調用android對象等於調用Android映射的對象
android.hello("js調用了android中的hello方法!!!");
}
- alert()、confirm()、prompt()
通過重寫WebChromeClient的onJsAlert()、onJsConfirm()、onJsPrompt()方法響應Js的alert()、confirm()、prompt()調用。
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Alert")
.setMessage(message)
.setPositiveButton(android.R.string.ok, (dialog, which) -> result.confirm())
.setNegativeButton(android.R.string.cancel, (dialog, which) -> result.cancel())
.setCancelable(false)
.create()
.show();
return true;
}
});
Js代碼
function callAndroidAlert(){
alert("來自Js的提示");
}
-
shouldOverrideUrlLoading
Js與Android定義一組特殊的URL,然後重寫WebViewClient的shouldOverrideUrlLoading()方法,攔截url,解析url包含的數據,針對不同數據做不同操作。
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.contains("protocol://webview?")) {
Map<String, String> dataMap = getUrlDataMap(url);
if (dataMap != null) {
switch (dataMap.get("operate")) {
case "toast":
Toast.makeText(MainActivity.this, dataMap.get("msg"), Toast.LENGTH_LONG).show();
break;
case "startActivity":
/*...*/
break;
default:
break;
}
}
} else
view.loadUrl(url);
return true;
}
});
/**
* 獲取URl所包含的數據
* @param url
* @return 數據的map集合
*/
private Map<String, String> getUrlDataMap(String url) {
Map<String, String> map = null;
try {
url = URLDecoder.decode(url, "utf-8");
String substring = url.substring(url.indexOf("?") + 1);
String[] split = substring.split("&");
map = new HashMap<>();
String[] entry;
for (String s : split) {
entry = s.split("=");
map.put(entry[0], entry[1]);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return map;
}
Js代碼
//這裏用一個a標籤做示例
<a href="protocol://webview?operate=toast&msg=Js通過url控制Android執行方法">通過url執行方法</a>
擴展方式
Js和Android的交互還可以通過JsBridge來完成,JsBridge是一個開源的第三方庫,其作用和名字一樣,可以作爲Js和Android之間的橋樑進行溝通。使用方法在Github上都有介紹,網上也有挺多博客的,有興趣的自己搜一下,我就不寫了。
總結
以上所有的Js和Android的交互方法,各有各的特點,其中Js調用Android的方法中,使用攔截Url的方式比較多,因爲考慮到要兼顧ios的通用性,攔截Url是兩個端實現成本最低的一種,如果不需要考慮ios端,那麼隨便哪一種都可以。