目錄
如何實作
本範例程式碼
呼叫範例
js呼叫Java
Java呼叫JS
函數" >呼叫js無參無回傳值函數
呼叫js有參無回傳值函數
呼叫js有參數有回傳值的函數
4.4處理
疑問解答
Alert無法彈出" >Alert無法彈出
Uncaught ReferenceError: functionName is not defined" >Uncaught ReferenceError: functionName is not defined
#Uncaught TypeError: Object [object Object] has no method" >#Uncaught TypeError: Object [object Object] has no method
#安全限制問題
首頁 web前端 js教程 Android中Java和JavaScript互動的詳解

Android中Java和JavaScript互動的詳解

Mar 15, 2017 pm 05:30 PM

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 &#39;JavaBridge&#39;. 
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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

小米紅米 Note 14 Pro Plus 上市,成為首款配備 Light Hunter 800 相機的高通 Snapdragon 7s Gen 3 智慧型手機 小米紅米 Note 14 Pro Plus 上市,成為首款配備 Light Hunter 800 相機的高通 Snapdragon 7s Gen 3 智慧型手機 Sep 27, 2024 am 06:23 AM

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系列的主角。李

從早期圖片來看,Oppo Find X8 的設計看起來像是蘋果 iPhone 16 Pro 和 OnePlus Open 的結合體 從早期圖片來看,Oppo Find X8 的設計看起來像是蘋果 iPhone 16 Pro 和 OnePlus Open 的結合體 Sep 28, 2024 am 06:04 AM

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

突破或從Java 8流返回? 突破或從Java 8流返回? Feb 07, 2025 pm 12:09 PM

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

聯想公佈 2024 年 Legion Y700 遊戲平板電腦的新顏色選項 聯想公佈 2024 年 Legion Y700 遊戲平板電腦的新顏色選項 Sep 29, 2024 am 06:05 AM

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

Java程序查找膠囊的體積 Java程序查找膠囊的體積 Feb 07, 2025 am 11:37 AM

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

如何在Spring Tool Suite中運行第一個春季啟動應用程序? 如何在Spring Tool Suite中運行第一個春季啟動應用程序? Feb 07, 2025 pm 12:11 PM

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

三星 Galaxy Z Fold 特別版透露將於 10 月底登陸,但名稱出現衝突 三星 Galaxy Z Fold 特別版透露將於 10 月底登陸,但名稱出現衝突 Oct 01, 2024 am 06:21 AM

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

創造未來:零基礎的 Java 編程 創造未來:零基礎的 Java 編程 Oct 13, 2024 pm 01:32 PM

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

See all articles