Android提供了一個很強大的WebView控件用來處理Web網頁,而在網頁中,JavaScript又是一個很舉足輕重的腳本。本文將介紹如何實現Java代碼和Javascript代碼的相互調用。
如何實現
實現Java和js交互十分便捷。通常只需要以下幾步。
1.WebView開啟JavaScript腳本執行
2.WebView設置供JavaScript調用的交互接口。
3.客戶端和網頁端編寫調用對方的代碼。
本例代碼
為了便于講解,先貼出全部代碼
Java代碼
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
public class MainActivity extends Activity {
private static final String LOGTAG = "MainActivity";
@SuppressLint("JavascriptInterface")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WebView myWebView = (WebView) findViewById(R.id.myWebView);
WebSettings settings = myWebView.getSettings();
settings.setJavaScriptEnabled(true);
myWebView.addJavascriptInterface(new JsInteration(), "control");
myWebView.setWebChromeClient(new WebChromeClient() {});
myWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
testMethod(myWebView);
}
});
myWebView.loadUrl("file:///android_asset/js_java_interaction.html");
}
private void testMethod(WebView webView) {
String call = "javascript:sayHello()";
call = "javascript:alertMessage(/"" + "content" + "/")";
call = "javascript:toastMessage(/"" + "content" + "/")";
call = "javascript:sumToJava(1,2)";
webView.loadUrl(call);
}
public class JsInteration {
@JavascriptInterface
public void toastMessage(String message) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
}
@JavascriptInterface
public void onSumResult(int result) {
Log.i(LOGTAG, "onSumResult result=" + result);
}
}
}
前端網頁代碼
function alertMessage(message) {
alert(message)
}
function toastMessage(message) {
window.control.toastMessage(message)
}
function sumToJava(number1, number2){
window.control.onSumResult(number1 + number2)
}
</script>
Java-Javascript Interaction In Android
</html>
調用示例
js調用Java
調用格式為window.jsInterfaceName.methodName(parameterValues) 此例中我們使用的是control作為注入接口名稱。
function sumToJava(number1, number2){
window.control.onSumResult(number1 + number2)
}
Java調用JS
webView調用js的基本格式為webView.loadUrl(“javascript:methodName(parameterValues)”)
調用js無參無返回值函數
調用js有參無返回值函數
注意對于字符串作為參數值需要進行轉義雙引號。
調用js有參數有返回值的函數
Android在4.4之前并沒有提供直接調用js函數并獲取值的方法,所以在此之前,常用的思路是 java調用js方法,js方法執行完畢,再次調用java代碼將值返回。
1.Java調用js代碼
2.js函數處理,并將結果通過調用java方法返回
3.Java在回調方法中獲取js函數返回值
4.4處理
Android 4.4之后使用evaluateJavascript即可。這里展示一個簡單的交互示例 具有返回值的js方法
java代碼時用evaluateJavascript方法調用
@Override
public void onReceiveValue(String value) {
Log.i(LOGTAG, "onReceiveValue value=" + value);
}});
}
輸出結果
注意
1.上面限定了結果返回結果為String,對于簡單的類型會嘗試轉換成字符串返回,對于復雜的數據類型,建議以字符串形式的json返回。
2.evaluateJavascript方法必須在UI線程(主線程)調用,因此onReceiveValue也執行在主線程。
疑問解答
Alert無法彈出
你應該是沒有設置WebChromeClient,按照以下代碼設置
問題出現原因,網頁的js代碼沒有加載完成,就調用了js方法。解決方法是在網頁加載完成之后調用js方法
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
//在這里執行你想調用的js函數
}
});
Uncaught TypeError: Object [object Object] has no method
安全限制問題
如果只在4.2版本以上的機器出問題,那么就是系統處于安全限制的問題了。Android文檔這樣說的
解決方法
1.將targetSdkVersion設置成17或更高,引入@JavascriptInterface注釋
2.自己創建一個注釋接口名字為@JavascriptInterface,然后將其引入。注意這個接口不能混淆。這種方式不推薦,大概在4.4之后有問題。
注,創建@JavascriptInterface代碼
}
代碼混淆問題
如果在沒有混淆的版本運行正常,在混淆后的版本的代碼運行錯誤,并提示Uncaught TypeError: Object [object Object] has no method,那就是你沒有做混淆例外處理。 在混淆文件加入類似這樣的代碼
All WebView methods must be called on the same thread
過濾日志曾發現過這個問題。
在js調用后的Java回調線程并不是主線程。如打印日志可驗證
解決上述的異常,將webview操作放在主線程中即可。
新聞熱點
疑難解答
圖片精選