android 的webView載入h5,和h5的互動(java和JavaScript的互動)

pszh發表於2016-08-02

Android提供了一個很強大的WebView控制元件用來處理Web網頁,而在網頁中,JavaScript又是一個很舉足輕重的指令碼。本文將介紹如何實現Java程式碼和Javascript程式碼的相互呼叫。(通俗點說就是,點選那個Web頁面的按鈕啥的,可以傳到原生app;或者原生app呼叫Web頁面的js方法)

如何實現

實現Java和js互動十分便捷。通常只需要以下幾步。

  • WebView開啟JavaScript指令碼執行
  • WebView設定供JavaScript呼叫的互動介面。
  • 客戶端和網頁端編寫呼叫對方的程式碼。

本例程式碼

為了便於講解,先貼出全部程式碼

Java程式碼

package com.example.testjs;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
//參考文件http://www.igooda.cn/jzjl/20141212737.html
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);
		//注入介面
		//js_java_interaction.html檔案中的toastMessage(),sumToJava()方法中的window後面的欄位
		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()";
//
//		String call = "javascript:alertMessage(\"" + "content" + "\")";
//
//		String call = "javascript:toastMessage(\"" + "content" + "\")";

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

	}
	//返回結果的處理
	public class JsInteration {

		@JavascriptInterface
		public void toastMessage(String message) {
			Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
		}
//		onSumResult欄位和 window.control.onSumResult(number1 + number2)中的onSumResult一樣
		@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>

下面介紹下

如何呼叫  

(1)addJavascriptInterface方法

此方法有兩個引數,第一個引數就是我們一般會實現一個自己的類,類裡面提供我們要提供給javascript訪問的方法;第二個引數是訪問我們在obj中宣告的方法時候所用到的js物件,呼叫模式為window.interfaceName.方法名()或者是javascript: interfaceName.方法名() ;,如myWebView.addJavascriptInterface(new JsInteration(), "control");
(2)js呼叫Java

呼叫格式為window.jsInterfaceName.methodName(parameterValues) 此例中我們使用的是control作為注入介面名稱。

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

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

(3)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也執行在主執行緒。
好了總體的就這麼多了

還有一些錯誤的話可以參考,程式碼混淆的話參考原文: http://www.igooda.cn/jzjl/20141212737.html
最後貼下文中使用的demo吧:http://www.oschina.net/code/snippet_2702417_58168

當然如果覺得這邊不太好的話還可以看看:http://www.cnblogs.com/lee0oo0/archive/2012/08/01/2617953.html

相關文章