Android筆記之 Webview與Js互動-詳情舉例
Android呼叫網頁自身Js
你好! 這是你第一次使用 Markdown編輯器 所展示的歡迎頁。如果你想學習如何使用Markdown編輯器, 可以仔細閱讀這篇文章,瞭解一下Markdown的基本語法知識。
本地(asset)網頁androidcalljs.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>android呼叫js</title>
<script>
function JsSelf(){
document. getElementById("demo").innerHTML="網頁自身呼叫JS";
}
function JsUseEvaluateJavascript(){
document.getElementById("demo2").innerHTML="Android呼叫網頁自身Js UseEvaluateJavascript";
return "Android呼叫網頁自身Js UseEvaluateJavascript";
}
function JsUseLoadUrl(){
document.getElementById("demo1").innerHTML="Android呼叫網頁自身Js UseLoadUrl" ;
}
</script>
</head>
<body>
<h1>android呼叫js</h1>
<p id="demo">網頁呼叫js</p>
<p id="demo1">呼叫js loadUrl</p>
<p id="demo2">呼叫js useEvaluateJavascript</p>
<button type="button" onclick="JsSelf()">網頁自身呼叫JS</button>
</body>
< /html>
上面網頁自身包含3個JavaScript函式
1、“loadUrl”呼叫網頁自身js
String script = "javascript:JsUseLoadUrl()";
mWebView.loadUrl(script);
以上程式碼中JsUseLoadUrl()
對應的是網頁自身JavaScript裡面的function函式。
2、“evaluateJavascript”呼叫網頁自身js
String script = "javascript:JsUseEvaluateJavascript()";
mWebView.evaluateJavascript(script, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
//value的值為 JavaScript執行 JsUseEvaluateJavascript()方法後的返回值
//即 “Android呼叫網頁自身Js UseEvaluateJavascript”
Log.e(TAG,value);
}
});
同理,以上程式碼中JsUseEvaluateJavascript()
對應的是網頁自身JavaScript裡面的function函式。
這裡注意的是“evaluateJavascript
”的引數列表,第一個引數是要執行的js,第二個則是Js函式執行後如果帶有返回值,這裡將在onReceiveValue
方法中接收該值,同時注意該值型別為String
。
3、區別
loadUrl
不帶返回值,會重新整理介面;
evaluateJavascript
帶返回值,不會重新整理介面,但需要API 19以後使用。
Android注入Js並呼叫
loadUrl
String script = "javascript:(function(){" +
"document.getElementById(\"demo1\").innerHTML=\"Android注入Js並呼叫 UseLoadUrl\";" +
"}())";
mWebView.loadUrl(script);
evaluateJavascript
String script = "javascript:(function(){" +
"document.getElementById(\"demo2\").innerHTML=\"Android呼叫外部Js useEvaluateJavascriptOut\";" +
"return \"Android呼叫外部Js useEvaluateJavascriptOut\";}())";
mWebView.evaluateJavascript(script, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
}
});
兩種注入JS沒有區別,需要注意的是注入的JavaScript格式:
"javascript:(function(){" +
//TODO 注意圓括號 花括號
"}())";
Js呼叫Android方法
JavaScript呼叫Android方法的HTML檔案
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>js呼叫android</title>
<script>
function JsUseEvaluateJavascript(text){
document.getElementById("withparms").innerHTML="js呼叫android帶參成功 android返回的值是:"+text;
return "Android呼叫Js UseEvaluateJavascript";
}
function JsUseLoadUrl(){
document.getElementById("noparm").innerHTML="js呼叫android方法成功 android呼叫js";
}
function callAndroidnoParms(){
android.callAndroidnoParms();
}
</script>
</head>
<body>
<h1>js呼叫android</h1>
<p id="withparms">等待android反饋</p>
<p id="noparm">等待android反饋</p>
<button type="button" onclick="callAndroidnoParms()">JS呼叫android方法</button>
<button type="button" onclick="window.android.callAndroidwithParms('我是引數')">JS帶引數呼叫android方法
</button>
</body>
</html>
webview.addJavascriptInterface(object,String)
1、在Activity中的需要被呼叫的方法添加註解@JavascriptInterface
@JavascriptInterface
public void callAndroidnoParms() {
runOnUiThread(new Runnable() {
@Override
public void run() {
String script = "javascript:JsUseLoadUrl()";
mWebView.loadUrl(script);
}
});
}
上面方法callAndroidnoParms
是要被JavaScript呼叫的方法,呼叫成功之後,run
方法裡面再從Android這邊呼叫Js。
注意
上面呼叫callAndroidnoParms
成功之後,如果要對webview做其他操作,必須要和生成webview的執行緒在同一執行緒中,比如在主執行緒例項化的webview,這裡就要使用runOnUiThread
,否則會報錯(不會引起程式崩潰)
java.lang.RuntimeException: java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. (Expected Looper Looper (main, tid 1) {4a7b4bb0} called on Looper (JavaBridge, tid 76) {4a7ba6d0}, FYI main Looper is Looper (main, tid 1) {4a7b4bb0})
2、mWebView.addJavascriptInterface(object, String);
使用addJavascriptInterface
方法,其中object
引數是對映成JavaScript
的物件,String
是給該對映物件取的別名。
比如 mWebView.addJavascriptInterface(this, "android");
該句話的意思就是把當前物件(Activity)對映成JavaScript的物件,android
就是對該對映物件取的別名,該別名在JavaScript呼叫Activity的方法會用到。
3、JavaScript呼叫
<!--JavaScript標籤裡面的方法-->
function callAndroidnoParms(){
android.callAndroidnoParms();
}
<!--body標籤裡面的按鈕-->
<button type="button" onclick="callAndroidnoParms()">JS呼叫android方法</button>
上面android.callAndroidnoParms()
意思就是執行android別名(Activity)裡面的callAndroidnoParms()方法,也就是上面 第1點添加註解的那個方法。
還有一種方式就是
<!--body標籤裡面的按鈕-->
<button type="button" onclick="window.android.callAndroidwithParms('我是引數')">JS帶引數呼叫android方法
</button>
在Activity裡面
@JavascriptInterface
public void callAndroidwithParms(final String text) {
runOnUiThread(new Runnable() {
@Override
public void run() {
//這裡text的值=“我是引數” 即HTML網頁裡面傳遞過來的
String script = "javascript:JsUseEvaluateJavascript('" + text + "')";
//android呼叫js
mWebView.evaluateJavascript(script, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
//value的值=Android呼叫Js UseEvaluateJavascript
}
});
}
});
}
上面是呼叫帶有引數的方法,使用的方式是window.android.callAndroidwithParms('我是引數')
。
當然上面呼叫不帶引數的方法,即上面callAndroidnoParms
方法,也可以使用window.android.callAndroidnoParms()
方式
<button type="button" onclick="window.android.callAndroidnoParms()">JS呼叫android方法</button>
網上還有其他方式,即監聽webview的某些方法,攔截處理,來實現android與js之間的互動,比如:shouldOverrideUrlLoading,onPageFinished,onProgressChanged,onJsAlert,onJsConfirm等等。 通常是在onProgressChanged或者onPageFinished方法裡面注入js,修改原HTML的佈局樣式等。