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 { }程式碼混淆問題如果在沒有混淆的版本運行正常,則混淆後的版本的程式碼執行錯誤,並提示Uncaught TypeError: Object [object Object] has no method,那就是你沒有做混淆例外處理。 在混淆檔案中加入類似這樣的程式碼
-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回呼執行緒並不是主執行緒。如列印日誌可驗證ThreadInfo=Thread[WebViewCoreThread,5,main]解決上述的異常,將webview操作放在主執行緒中即可。
webView.post(new Runnable() { @Override public void run() { webView.loadUrl(YOUR_URL). } });#
以上是Android中Java和JavaScript互動的詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

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

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

WebStorm Mac版
好用的JavaScript開發工具