Android中Java和JavaScript互動的詳解
Android提供了一個很強大的WebView控制項用來處理Web網頁,而在網頁中,JavaScript又是一個很舉足輕重的腳本。本文將介紹如何實作Java程式碼和Javascript程式碼的相互呼叫。
如何實作
實作Java和js互動十分便捷。通常只需要以下幾個步驟。
WebView開啟JavaScript腳本執行
WebView設定供JavaScript呼叫的互動介面。
客戶端和網頁端編寫呼叫對方的程式碼。
本範例程式碼
為了方便講解,先貼出全部程式碼
Java程式碼
package com.example.javajsinteractiondemo; 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); } } }
前端網頁程式碼
<html> <script type="text/javascript"> function sayHello() { alert("Hello") } 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 toastMessage(message) { window.control.toastMessage(message) } function sumToJava(number1, number2){ window.control.onSumResult(number1 + number2) }
Java呼叫JS
webView呼叫js的基本格式為webView.loadUrl(“javascript:methodName(parameterValues)”)
呼叫js無參無回傳值函數
String call = "javascript:sayHello()"; webView.loadUrl(call);
呼叫js有參無回傳值函數
注意對於字串作為參數值需要進行轉義雙引號。
String call = "javascript:alertMessage(\"" + "content" + "\")"; webView.loadUrl(call);
呼叫js有參數有回傳值的函數
Android在4.4之前並沒有提供直接呼叫js函數並取得值的方法,所以在此之前,常用的想法是java調用js方法,js方法執行完畢,再次呼叫java程式碼將值回傳。
1.Java呼叫js程式碼
String call = "javascript:sumToJava(1,2)"; webView.loadUrl(call);
2.js函數處理,並將結果透過呼叫java方法傳回
function sumToJava(number1, number2){ window.control.onSumResult(number1 + number2) }
3.Java在回呼方法中取得js函數傳回值
@JavascriptInterface public void onSumResult(int result) { Log.i(LOGTAG, "onSumResult result=" + result); }
4.4處理
Android 4.4之後使用evaluateJavascript即可。這裡展示一個簡單的互動範例具有傳回值的js方法
function getGreetings() { return 1; }
java程式碼時用evaluateJavascript方法呼叫
private void testEvaluateJavascript(WebView webView) { webView.evaluateJavascript("getGreetings()", new ValueCallback<String>() { @Override public void onReceiveValue(String value) { Log.i(LOGTAG, "onReceiveValue value=" + value); }}); }
輸出結果
I/MainActivity( 1432): onReceiveValue value=1
注意
#上面限定了結果返回結果為String,對於簡單的類型會嘗試轉換成字串返回,對於複雜的資料類型,建議以字串形式的json返回。
evaluateJavascript方法必須在UI執行緒(主執行緒)調用,因此onReceiveValue也執行在主執行緒。
疑問解答
Alert無法彈出
你應該是沒有設定WebChromeClient,依照以下程式碼設定
myWebView.setWebChromeClient(new WebChromeClient() {});
Uncaught ReferenceError: functionName is not defined
問題出現原因,網頁的js程式碼沒有載入完成,就呼叫了js方法。解決方法是在網頁載入完成之後呼叫js方法
myWebView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); //在这里执行你想调用的js函数 } });
#Uncaught TypeError: Object [object Object] has no method
#安全限制問題
如果只在4.2版本以上的機器出問題,那就是系統處於安全限制的問題了。 Android文件這樣說的
Caution: If you've set your targetSdkVersion to 17 or higher, you must add the @JavascriptInterface annotation to any method that you want available your web page codethe method also be public). If you do not provide the annotation, then the method will not accessible by your web page when running on Android 4.2 或 higher.
f ##警告:如果你的程式目標平台是17或更高,你必須在暴露給網頁可呼叫的方法(這個方法必須是公開的)加上@JavascriptInterface
註解。如果你不這麼做的話,在4.2以以後的平台上,網頁無法存取你的方法。#將targetSdkVersion設定為17或更高,引入@JavascriptInterface註解
- 自行建立一個註解介面名字為@JavascriptInterface,然後將其引入。注意這個介面不能混淆。
- 註,創建@JavascriptInterface程式碼
public @interface JavascriptInterface { }
-keep class com.example.javajsinteractiondemo$JsInteration {
*;
}
登入後複製
-keep class com.example.javajsinteractiondemo$JsInteration { *; }
All WebView methods must be called on the same thread
過濾日誌曾經發現過這個問題。 E/StrictMode( 1546): 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) {528712d4} called on Looper (JavaBridge, tid 121) {52b6678c},
FYI main Looper is Looper (main, tid 1) {528712d4})
E/StrictMode( 1546): at android.webkit.WebView.checkThread(WebView.java:2063)
E/StrictMode( 1546): at android.webkit.WebView.loadUrl(WebView.java:794)
E/StrictMode( 1546): at com.xxx.xxxx.xxxx.xxxx.xxxxxxx$JavaScriptInterface.onCanGoBackResult(xxxx.java:96)
E/StrictMode( 1546): at com.android.org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
E/StrictMode( 1546): at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:27)
E/StrictMode( 1546): at android.os.Handler.dispatchMessage(Handler.java:102)
E/StrictMode( 1546): at android.os.Looper.loop(Looper.java:136)
E/StrictMode( 1546): at android.os.HandlerThread.run(HandlerThread.java:61)
登入後複製
在js呼叫後的Java回呼執行緒並不是主執行緒。如列印日誌可驗證E/StrictMode( 1546): 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) {528712d4} called on Looper (JavaBridge, tid 121) {52b6678c}, FYI main Looper is Looper (main, tid 1) {528712d4}) E/StrictMode( 1546): at android.webkit.WebView.checkThread(WebView.java:2063) E/StrictMode( 1546): at android.webkit.WebView.loadUrl(WebView.java:794) E/StrictMode( 1546): at com.xxx.xxxx.xxxx.xxxx.xxxxxxx$JavaScriptInterface.onCanGoBackResult(xxxx.java:96) E/StrictMode( 1546): at com.android.org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method) E/StrictMode( 1546): at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:27) E/StrictMode( 1546): at android.os.Handler.dispatchMessage(Handler.java:102) E/StrictMode( 1546): at android.os.Looper.loop(Looper.java:136) E/StrictMode( 1546): at android.os.HandlerThread.run(HandlerThread.java:61)
ThreadInfo=Thread[WebViewCoreThread,5,main]
webView.post(new Runnable() { @Override public void run() { webView.loadUrl(YOUR_URL). } });
以上是Android中Java和JavaScript互動的詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

Redmi Note 14 Pro Plus 現已正式成為去年 Redmi Note 13 Pro Plus 的直接後繼產品(亞馬遜售價 375 美元)。正如預期的那樣,Redmi Note 14 Pro Plus與Redmi Note 14和Redmi Note 14 Pro一起成為Redmi Note 14系列的主角。李

從歷史上看,除了2018 年6 月發布的初代Find X 之外,Oppo 都會在冬末或初春更新其旗艦產品「Find X」系列。一點在此刻。 H

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

聯想正準備在9月29日於中國推出2024款Legion Y700。這款新的 Android 遊戲平板電腦將與 RedMagic Nova 競爭,該公司已經確認了該設備的幾乎所有規格。現在,距離全面開賽還有幾個小時

膠囊是一種三維幾何圖形,由一個圓柱體和兩端各一個半球體組成。膠囊的體積可以通過將圓柱體的體積和兩端半球體的體積相加來計算。本教程將討論如何使用不同的方法在Java中計算給定膠囊的體積。 膠囊體積公式 膠囊體積的公式如下: 膠囊體積 = 圓柱體體積 兩個半球體體積 其中, r: 半球體的半徑。 h: 圓柱體的高度(不包括半球體)。 例子 1 輸入 半徑 = 5 單位 高度 = 10 單位 輸出 體積 = 1570.8 立方單位 解釋 使用公式計算體積: 體積 = π × r2 × h (4

Spring Boot簡化了可靠,可擴展和生產就緒的Java應用的創建,從而徹底改變了Java開發。 它的“慣例慣例”方法(春季生態系統固有的慣例),最小化手動設置

三星期待已久的「特別版」可折疊手機的推出又迎來了另一個轉折。最近幾週,有關所謂 Galaxy Z Fold 特別版的傳言相當安靜。相反,焦點已轉移到 Galaxy S25 系列,包括

Java是熱門程式語言,適合初學者和經驗豐富的開發者學習。本教學從基礎概念出發,逐步深入解說進階主題。安裝Java開發工具包後,可透過建立簡單的「Hello,World!」程式來實踐程式設計。理解程式碼後,使用命令提示字元編譯並執行程序,控制台上將輸出「Hello,World!」。學習Java開啟了程式設計之旅,隨著掌握程度加深,可創建更複雜的應用程式。
