a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 系統(tǒng) > Android > 正文

Android中Java和JavaScript交互實(shí)例

2020-04-11 11:41:32
字體:
供稿:網(wǎng)友

Android提供了一個很強(qiáng)大的WebView控件用來處理Web網(wǎng)頁,而在網(wǎng)頁中,JavaScript又是一個很舉足輕重的腳本。本文將介紹如何實(shí)現(xiàn)Java代碼和Javascript代碼的相互調(diào)用。

如何實(shí)現(xiàn)

實(shí)現(xiàn)Java和js交互十分便捷。通常只需要以下幾步。

1.WebView開啟JavaScript腳本執(zhí)行
2.WebView設(shè)置供JavaScript調(diào)用的交互接口。
3.客戶端和網(wǎng)頁端編寫調(diào)用對方的代碼。

本例代碼

為了便于講解,先貼出全部代碼

Java代碼

復(fù)制代碼 代碼如下:

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);
      }
  }

}

前端網(wǎng)頁代碼

復(fù)制代碼 代碼如下:

<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>

調(diào)用示例

js調(diào)用Java

調(diào)用格式為window.jsInterfaceName.methodName(parameterValues) 此例中我們使用的是control作為注入接口名稱。

復(fù)制代碼 代碼如下:

function toastMessage(message) {
  window.control.toastMessage(message)
}

function sumToJava(number1, number2){
   window.control.onSumResult(number1 + number2)
}

Java調(diào)用JS

webView調(diào)用js的基本格式為webView.loadUrl(“javascript:methodName(parameterValues)”)

調(diào)用js無參無返回值函數(shù)

復(fù)制代碼 代碼如下:

String call = "javascript:sayHello()";
webView.loadUrl(call);

調(diào)用js有參無返回值函數(shù)

注意對于字符串作為參數(shù)值需要進(jìn)行轉(zhuǎn)義雙引號。

復(fù)制代碼 代碼如下:

String call = "javascript:alertMessage(/"" + "content" + "/")";
webView.loadUrl(call);

調(diào)用js有參數(shù)有返回值的函數(shù)

Android在4.4之前并沒有提供直接調(diào)用js函數(shù)并獲取值的方法,所以在此之前,常用的思路是 java調(diào)用js方法,js方法執(zhí)行完畢,再次調(diào)用java代碼將值返回。

1.Java調(diào)用js代碼

復(fù)制代碼 代碼如下:

String call = "javascript:sumToJava(1,2)";
webView.loadUrl(call);

2.js函數(shù)處理,并將結(jié)果通過調(diào)用java方法返回

復(fù)制代碼 代碼如下:

function sumToJava(number1, number2){
       window.control.onSumResult(number1 + number2)
}

3.Java在回調(diào)方法中獲取js函數(shù)返回值

復(fù)制代碼 代碼如下:

@JavascriptInterface
public void onSumResult(int result) {
  Log.i(LOGTAG, "onSumResult result=" + result);
}

4.4處理

Android 4.4之后使用evaluateJavascript即可。這里展示一個簡單的交互示例 具有返回值的js方法

復(fù)制代碼 代碼如下:

function getGreetings() {
      return 1;
}

java代碼時用evaluateJavascript方法調(diào)用

復(fù)制代碼 代碼如下:

private void testEvaluateJavascript(WebView webView) {
  webView.evaluateJavascript("getGreetings()", new ValueCallback<String>() {

  @Override
  public void onReceiveValue(String value) {
      Log.i(LOGTAG, "onReceiveValue value=" + value);
  }});
}

輸出結(jié)果

復(fù)制代碼 代碼如下:

I/MainActivity( 1432): onReceiveValue value=1

注意

1.上面限定了結(jié)果返回結(jié)果為String,對于簡單的類型會嘗試轉(zhuǎn)換成字符串返回,對于復(fù)雜的數(shù)據(jù)類型,建議以字符串形式的json返回。
2.evaluateJavascript方法必須在UI線程(主線程)調(diào)用,因此onReceiveValue也執(zhí)行在主線程。

疑問解答

Alert無法彈出

你應(yīng)該是沒有設(shè)置WebChromeClient,按照以下代碼設(shè)置

復(fù)制代碼 代碼如下:

myWebView.setWebChromeClient(new WebChromeClient() {});
Uncaught ReferenceError: functionName is not defined

問題出現(xiàn)原因,網(wǎng)頁的js代碼沒有加載完成,就調(diào)用了js方法。解決方法是在網(wǎng)頁加載完成之后調(diào)用js方法

復(fù)制代碼 代碼如下:

myWebView.setWebViewClient(new WebViewClient() {

  @Override
  public void onPageFinished(WebView view, String url) {
      super.onPageFinished(view, url);
      //在這里執(zhí)行你想調(diào)用的js函數(shù)
  }
 
});

Uncaught TypeError: Object [object Object] has no method

安全限制問題

如果只在4.2版本以上的機(jī)器出問題,那么就是系統(tǒng)處于安全限制的問題了。Android文檔這樣說的

復(fù)制代碼 代碼如下:

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 code (the method must 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 or higher.

中文大意為
復(fù)制代碼 代碼如下:

警告:如果你的程序目標(biāo)平臺是17或者是更高,你必須要在暴露給網(wǎng)頁可調(diào)用的方法(這個方法必須是公開的)加上@JavascriptInterface注釋。如果你不這樣做的話,在4.2以以后的平臺上,網(wǎng)頁無法訪問到你的方法。

解決方法

1.將targetSdkVersion設(shè)置成17或更高,引入@JavascriptInterface注釋
2.自己創(chuàng)建一個注釋接口名字為@JavascriptInterface,然后將其引入。注意這個接口不能混淆。這種方式不推薦,大概在4.4之后有問題。

注,創(chuàng)建@JavascriptInterface代碼

復(fù)制代碼 代碼如下:

public @interface JavascriptInterface {

}

代碼混淆問題

如果在沒有混淆的版本運(yùn)行正常,在混淆后的版本的代碼運(yùn)行錯誤,并提示Uncaught TypeError: Object [object Object] has no method,那就是你沒有做混淆例外處理。 在混淆文件加入類似這樣的代碼

復(fù)制代碼 代碼如下:

-keep class com.example.javajsinteractiondemo$JsInteration {
    *;
}

All WebView methods must be called on the same thread

過濾日志曾發(fā)現(xiàn)過這個問題。

復(fù)制代碼 代碼如下:

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調(diào)用后的Java回調(diào)線程并不是主線程。如打印日志可驗(yàn)證

復(fù)制代碼 代碼如下:

ThreadInfo=Thread[WebViewCoreThread,5,main]

解決上述的異常,將webview操作放在主線程中即可。

復(fù)制代碼 代碼如下:

webView.post(new Runnable() {
    @Override
    public void run() {
        webView.loadUrl(YOUR_URL).
    }
});

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 草久网| 黄色欧美视频 | 九九人人 | 久久全国免费视频 | 97精品视频在线观看 | 天堂va | 欧美一区高清 | 青青草免费在线观看 | 久久久久久久久久久久久久久 | 亚洲www | 黄色一级电影 | 亚洲电影一区二区 | 欧美午夜视频在线观看 | 日韩高清二区 | 欧美精品导航 | 黄色福利影院 | 亚洲精品视频一区 | 欧美手机在线 | 久久99精品久久久久久久青青日本 | 日韩欧美一区二区三区免费观看 | 亚洲福利国产 | 欧美日韩一区二区三区在线观看 | 九九热精品视频在线 | 9999国产精品| 污视频网站在线看 | 欧美在线xxx| 99re热精品视频 | 亚洲国产区 | 国产精品一卡二卡三卡 | h免费在线 | 亚洲国产精品人人爽夜夜爽 | 久久99国产精一区二区三区 | 99国产精品久久久久老师 | 青青草久久 | segui88久久综合9999 | 看全黄大色黄大片老人做 | 爱草视频 | 国产人久久人人人人爽 | 亚洲精品午夜aaa久久久 | 日韩特黄一级欧美毛片特黄 | 91观看|