html5中文学习网

您的位置: 首页 > android » 正文

Android中Java和JavaScript交互实例_Android

[ ] 已经帮助:人解决问题

Android提供了一个很强大的WebView控件用来处理Web网页,而在网页中,JavaScript又是一个很举足轻重的脚本。本文将介绍如何实现Java代码和Javascript代码的相互调用。MXKHTML5中文学习网 - HTML5先行者学习网

如何实现MXKHTML5中文学习网 - HTML5先行者学习网

实现Java和js交互十分便捷。通常只需要以下几步。MXKHTML5中文学习网 - HTML5先行者学习网

1.WebView开启JavaScript脚本执行MXKHTML5中文学习网 - HTML5先行者学习网
2.WebView设置供JavaScript调用的交互接口。MXKHTML5中文学习网 - HTML5先行者学习网
3.客户端和网页端编写调用对方的代码。MXKHTML5中文学习网 - HTML5先行者学习网

本例代码MXKHTML5中文学习网 - HTML5先行者学习网

为了便于讲解,先贴出全部代码MXKHTML5中文学习网 - HTML5先行者学习网

Java代码MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
package com.example.javajsinteractiondemo;MXKHTML5中文学习网 - HTML5先行者学习网

import android.annotation.SuppressLint;MXKHTML5中文学习网 - HTML5先行者学习网
import android.app.Activity;MXKHTML5中文学习网 - HTML5先行者学习网
import android.os.Bundle;MXKHTML5中文学习网 - HTML5先行者学习网
import android.util.Log;MXKHTML5中文学习网 - HTML5先行者学习网
import android.view.Menu;MXKHTML5中文学习网 - HTML5先行者学习网
import android.webkit.JavascriptInterface;MXKHTML5中文学习网 - HTML5先行者学习网
import android.webkit.WebChromeClient;MXKHTML5中文学习网 - HTML5先行者学习网
import android.webkit.WebSettings;MXKHTML5中文学习网 - HTML5先行者学习网
import android.webkit.WebView;MXKHTML5中文学习网 - HTML5先行者学习网
import android.webkit.WebViewClient;MXKHTML5中文学习网 - HTML5先行者学习网
import android.widget.Toast;MXKHTML5中文学习网 - HTML5先行者学习网

public class MainActivity extends Activity {MXKHTML5中文学习网 - HTML5先行者学习网
  private static final String LOGTAG = "MainActivity";MXKHTML5中文学习网 - HTML5先行者学习网
  @SuppressLint("JavascriptInterface")MXKHTML5中文学习网 - HTML5先行者学习网
  @OverrideMXKHTML5中文学习网 - HTML5先行者学习网
  protected void onCreate(Bundle savedInstanceState) {MXKHTML5中文学习网 - HTML5先行者学习网
      super.onCreate(savedInstanceState);MXKHTML5中文学习网 - HTML5先行者学习网
      setContentView(R.layout.activity_main);MXKHTML5中文学习网 - HTML5先行者学习网
      final WebView myWebView = (WebView) findViewById(R.id.myWebView);MXKHTML5中文学习网 - HTML5先行者学习网
      WebSettings settings = myWebView.getSettings();MXKHTML5中文学习网 - HTML5先行者学习网
      settings.setJavaScriptEnabled(true);MXKHTML5中文学习网 - HTML5先行者学习网
      myWebView.addJavascriptInterface(new JsInteration(), "control");MXKHTML5中文学习网 - HTML5先行者学习网
      myWebView.setWebChromeClient(new WebChromeClient() {});MXKHTML5中文学习网 - HTML5先行者学习网
      myWebView.setWebViewClient(new WebViewClient() {MXKHTML5中文学习网 - HTML5先行者学习网

          @OverrideMXKHTML5中文学习网 - HTML5先行者学习网
          public void onPageFinished(WebView view, String url) {MXKHTML5中文学习网 - HTML5先行者学习网
              super.onPageFinished(view, url);MXKHTML5中文学习网 - HTML5先行者学习网
              testMethod(myWebView);MXKHTML5中文学习网 - HTML5先行者学习网
          }MXKHTML5中文学习网 - HTML5先行者学习网
          MXKHTML5中文学习网 - HTML5先行者学习网
      });MXKHTML5中文学习网 - HTML5先行者学习网
      myWebView.loadUrl("file:///android_asset/js_java_interaction.html");MXKHTML5中文学习网 - HTML5先行者学习网
  }MXKHTML5中文学习网 - HTML5先行者学习网
  MXKHTML5中文学习网 - HTML5先行者学习网
  private void testMethod(WebView webView) {MXKHTML5中文学习网 - HTML5先行者学习网
      String call = "javascript:sayHello()";MXKHTML5中文学习网 - HTML5先行者学习网
      MXKHTML5中文学习网 - HTML5先行者学习网
      call = "javascript:alertMessage(/"" + "content" + "/")";MXKHTML5中文学习网 - HTML5先行者学习网
      MXKHTML5中文学习网 - HTML5先行者学习网
      call = "javascript:toastMessage(/"" + "content" + "/")";MXKHTML5中文学习网 - HTML5先行者学习网
      MXKHTML5中文学习网 - HTML5先行者学习网
      call = "javascript:sumToJava(1,2)";MXKHTML5中文学习网 - HTML5先行者学习网
      webView.loadUrl(call);MXKHTML5中文学习网 - HTML5先行者学习网
      MXKHTML5中文学习网 - HTML5先行者学习网
  }MXKHTML5中文学习网 - HTML5先行者学习网
  MXKHTML5中文学习网 - HTML5先行者学习网
  public class JsInteration {MXKHTML5中文学习网 - HTML5先行者学习网
      MXKHTML5中文学习网 - HTML5先行者学习网
      @JavascriptInterfaceMXKHTML5中文学习网 - HTML5先行者学习网
      public void toastMessage(String message) {MXKHTML5中文学习网 - HTML5先行者学习网
          Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();MXKHTML5中文学习网 - HTML5先行者学习网
      }MXKHTML5中文学习网 - HTML5先行者学习网
      MXKHTML5中文学习网 - HTML5先行者学习网
      @JavascriptInterfaceMXKHTML5中文学习网 - HTML5先行者学习网
      public void onSumResult(int result) {MXKHTML5中文学习网 - HTML5先行者学习网
          Log.i(LOGTAG, "onSumResult result=" + result);MXKHTML5中文学习网 - HTML5先行者学习网
      }MXKHTML5中文学习网 - HTML5先行者学习网
  }MXKHTML5中文学习网 - HTML5先行者学习网

}MXKHTML5中文学习网 - HTML5先行者学习网

MXKHTML5中文学习网 - HTML5先行者学习网

前端网页代码MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
<html>MXKHTML5中文学习网 - HTML5先行者学习网
<script type="text/javascript">MXKHTML5中文学习网 - HTML5先行者学习网
    function sayHello() {MXKHTML5中文学习网 - HTML5先行者学习网
        alert("Hello")MXKHTML5中文学习网 - HTML5先行者学习网
    }MXKHTML5中文学习网 - HTML5先行者学习网

    function alertMessage(message) {MXKHTML5中文学习网 - HTML5先行者学习网
        alert(message)MXKHTML5中文学习网 - HTML5先行者学习网
    }MXKHTML5中文学习网 - HTML5先行者学习网

    function toastMessage(message) {MXKHTML5中文学习网 - HTML5先行者学习网
        window.control.toastMessage(message)MXKHTML5中文学习网 - HTML5先行者学习网
    }MXKHTML5中文学习网 - HTML5先行者学习网

    function sumToJava(number1, number2){MXKHTML5中文学习网 - HTML5先行者学习网
       window.control.onSumResult(number1 + number2)MXKHTML5中文学习网 - HTML5先行者学习网
    }MXKHTML5中文学习网 - HTML5先行者学习网
</script>MXKHTML5中文学习网 - HTML5先行者学习网
Java-Javascript Interaction In AndroidMXKHTML5中文学习网 - HTML5先行者学习网
</html>MXKHTML5中文学习网 - HTML5先行者学习网

MXKHTML5中文学习网 - HTML5先行者学习网

调用示例MXKHTML5中文学习网 - HTML5先行者学习网

js调用JavaMXKHTML5中文学习网 - HTML5先行者学习网

调用格式为window.jsInterfaceName.methodName(parameterValues) 此例中我们使用的是control作为注入接口名称。MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
function toastMessage(message) {MXKHTML5中文学习网 - HTML5先行者学习网
  window.control.toastMessage(message)MXKHTML5中文学习网 - HTML5先行者学习网
}MXKHTML5中文学习网 - HTML5先行者学习网

function sumToJava(number1, number2){MXKHTML5中文学习网 - HTML5先行者学习网
   window.control.onSumResult(number1 + number2)MXKHTML5中文学习网 - HTML5先行者学习网
}MXKHTML5中文学习网 - HTML5先行者学习网

MXKHTML5中文学习网 - HTML5先行者学习网

Java调用JSMXKHTML5中文学习网 - HTML5先行者学习网

webView调用js的基本格式为webView.loadUrl(“javascript:methodName(parameterValues)”)MXKHTML5中文学习网 - HTML5先行者学习网

调用js无参无返回值函数MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
String call = "javascript:sayHello()";MXKHTML5中文学习网 - HTML5先行者学习网
webView.loadUrl(call);MXKHTML5中文学习网 - HTML5先行者学习网
MXKHTML5中文学习网 - HTML5先行者学习网

调用js有参无返回值函数MXKHTML5中文学习网 - HTML5先行者学习网

注意对于字符串作为参数值需要进行转义双引号。MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
String call = "javascript:alertMessage(/"" + "content" + "/")";MXKHTML5中文学习网 - HTML5先行者学习网
webView.loadUrl(call);MXKHTML5中文学习网 - HTML5先行者学习网
MXKHTML5中文学习网 - HTML5先行者学习网

调用js有参数有返回值的函数MXKHTML5中文学习网 - HTML5先行者学习网

Android在4.4之前并没有提供直接调用js函数并获取值的方法,所以在此之前,常用的思路是 java调用js方法,js方法执行完毕,再次调用java代码将值返回。MXKHTML5中文学习网 - HTML5先行者学习网

1.Java调用js代码MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
String call = "javascript:sumToJava(1,2)";MXKHTML5中文学习网 - HTML5先行者学习网
webView.loadUrl(call);MXKHTML5中文学习网 - HTML5先行者学习网
MXKHTML5中文学习网 - HTML5先行者学习网

2.js函数处理,并将结果通过调用java方法返回MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
function sumToJava(number1, number2){MXKHTML5中文学习网 - HTML5先行者学习网
       window.control.onSumResult(number1 + number2)MXKHTML5中文学习网 - HTML5先行者学习网
}MXKHTML5中文学习网 - HTML5先行者学习网
MXKHTML5中文学习网 - HTML5先行者学习网

3.Java在回调方法中获取js函数返回值MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
@JavascriptInterfaceMXKHTML5中文学习网 - HTML5先行者学习网
public void onSumResult(int result) {MXKHTML5中文学习网 - HTML5先行者学习网
  Log.i(LOGTAG, "onSumResult result=" + result);MXKHTML5中文学习网 - HTML5先行者学习网
}MXKHTML5中文学习网 - HTML5先行者学习网
MXKHTML5中文学习网 - HTML5先行者学习网

4.4处理MXKHTML5中文学习网 - HTML5先行者学习网

Android 4.4之后使用evaluateJavascript即可。这里展示一个简单的交互示例 具有返回值的js方法MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
function getGreetings() {MXKHTML5中文学习网 - HTML5先行者学习网
      return 1;MXKHTML5中文学习网 - HTML5先行者学习网
}MXKHTML5中文学习网 - HTML5先行者学习网
MXKHTML5中文学习网 - HTML5先行者学习网

java代码时用evaluateJavascript方法调用MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
private void testEvaluateJavascript(WebView webView) {MXKHTML5中文学习网 - HTML5先行者学习网
  webView.evaluateJavascript("getGreetings()", new ValueCallback<String>() {MXKHTML5中文学习网 - HTML5先行者学习网

  @OverrideMXKHTML5中文学习网 - HTML5先行者学习网
  public void onReceiveValue(String value) {MXKHTML5中文学习网 - HTML5先行者学习网
      Log.i(LOGTAG, "onReceiveValue value=" + value);MXKHTML5中文学习网 - HTML5先行者学习网
  }});MXKHTML5中文学习网 - HTML5先行者学习网
}MXKHTML5中文学习网 - HTML5先行者学习网

MXKHTML5中文学习网 - HTML5先行者学习网

输出结果MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
I/MainActivity( 1432): onReceiveValue value=1MXKHTML5中文学习网 - HTML5先行者学习网
MXKHTML5中文学习网 - HTML5先行者学习网

注意MXKHTML5中文学习网 - HTML5先行者学习网

1.上面限定了结果返回结果为String,对于简单的类型会尝试转换成字符串返回,对于复杂的数据类型,建议以字符串形式的json返回。MXKHTML5中文学习网 - HTML5先行者学习网
2.evaluateJavascript方法必须在UI线程(主线程)调用,因此onReceiveValue也执行在主线程。MXKHTML5中文学习网 - HTML5先行者学习网

疑问解答MXKHTML5中文学习网 - HTML5先行者学习网

Alert无法弹出MXKHTML5中文学习网 - HTML5先行者学习网

你应该是没有设置WebChromeClient,按照以下代码设置MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
myWebView.setWebChromeClient(new WebChromeClient() {});MXKHTML5中文学习网 - HTML5先行者学习网
Uncaught ReferenceError: functionName is not definedMXKHTML5中文学习网 - HTML5先行者学习网
MXKHTML5中文学习网 - HTML5先行者学习网

问题出现原因,网页的js代码没有加载完成,就调用了js方法。解决方法是在网页加载完成之后调用js方法MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
myWebView.setWebViewClient(new WebViewClient() {MXKHTML5中文学习网 - HTML5先行者学习网

  @OverrideMXKHTML5中文学习网 - HTML5先行者学习网
  public void onPageFinished(WebView view, String url) {MXKHTML5中文学习网 - HTML5先行者学习网
      super.onPageFinished(view, url);MXKHTML5中文学习网 - HTML5先行者学习网
      //在这里执行你想调用的js函数MXKHTML5中文学习网 - HTML5先行者学习网
  }MXKHTML5中文学习网 - HTML5先行者学习网
  MXKHTML5中文学习网 - HTML5先行者学习网
});MXKHTML5中文学习网 - HTML5先行者学习网

MXKHTML5中文学习网 - HTML5先行者学习网

Uncaught TypeError: Object [object Object] has no methodMXKHTML5中文学习网 - HTML5先行者学习网

安全限制问题MXKHTML5中文学习网 - HTML5先行者学习网

如果只在4.2版本以上的机器出问题,那么就是系统处于安全限制的问题了。Android文档这样说的MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
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.MXKHTML5中文学习网 - HTML5先行者学习网
MXKHTML5中文学习网 - HTML5先行者学习网
中文大意为MXKHTML5中文学习网 - HTML5先行者学习网
复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
警告:如果你的程序目标平台是17或者是更高,你必须要在暴露给网页可调用的方法(这个方法必须是公开的)加上@JavascriptInterface注释。如果你不这样做的话,在4.2以以后的平台上,网页无法访问到你的方法。MXKHTML5中文学习网 - HTML5先行者学习网
MXKHTML5中文学习网 - HTML5先行者学习网

解决方法MXKHTML5中文学习网 - HTML5先行者学习网

1.将targetSdkVersion设置成17或更高,引入@JavascriptInterface注释MXKHTML5中文学习网 - HTML5先行者学习网
2.自己创建一个注释接口名字为@JavascriptInterface,然后将其引入。注意这个接口不能混淆。这种方式不推荐,大概在4.4之后有问题。MXKHTML5中文学习网 - HTML5先行者学习网

注,创建@JavascriptInterface代码MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
public @interface JavascriptInterface {MXKHTML5中文学习网 - HTML5先行者学习网

}MXKHTML5中文学习网 - HTML5先行者学习网

MXKHTML5中文学习网 - HTML5先行者学习网

代码混淆问题MXKHTML5中文学习网 - HTML5先行者学习网

如果在没有混淆的版本运行正常,在混淆后的版本的代码运行错误,并提示Uncaught TypeError: Object [object Object] has no method,那就是你没有做混淆例外处理。 在混淆文件加入类似这样的代码MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
-keep class com.example.javajsinteractiondemo$JsInteration {MXKHTML5中文学习网 - HTML5先行者学习网
    *;MXKHTML5中文学习网 - HTML5先行者学习网
}MXKHTML5中文学习网 - HTML5先行者学习网
MXKHTML5中文学习网 - HTML5先行者学习网

All WebView methods must be called on the same threadMXKHTML5中文学习网 - HTML5先行者学习网

过滤日志曾发现过这个问题。MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
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})MXKHTML5中文学习网 - HTML5先行者学习网
E/StrictMode( 1546):   at android.webkit.WebView.checkThread(WebView.java:2063)MXKHTML5中文学习网 - HTML5先行者学习网
E/StrictMode( 1546):   at android.webkit.WebView.loadUrl(WebView.java:794)MXKHTML5中文学习网 - HTML5先行者学习网
E/StrictMode( 1546):   at com.xxx.xxxx.xxxx.xxxx.xxxxxxx$JavaScriptInterface.onCanGoBackResult(xxxx.java:96)MXKHTML5中文学习网 - HTML5先行者学习网
E/StrictMode( 1546):   at com.android.org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)MXKHTML5中文学习网 - HTML5先行者学习网
E/StrictMode( 1546):   at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:27)MXKHTML5中文学习网 - HTML5先行者学习网
E/StrictMode( 1546):   at android.os.Handler.dispatchMessage(Handler.java:102)MXKHTML5中文学习网 - HTML5先行者学习网
E/StrictMode( 1546):   at android.os.Looper.loop(Looper.java:136)MXKHTML5中文学习网 - HTML5先行者学习网
E/StrictMode( 1546):   at android.os.HandlerThread.run(HandlerThread.java:61)MXKHTML5中文学习网 - HTML5先行者学习网
MXKHTML5中文学习网 - HTML5先行者学习网

在js调用后的Java回调线程并不是主线程。如打印日志可验证MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
ThreadInfo=Thread[WebViewCoreThread,5,main]MXKHTML5中文学习网 - HTML5先行者学习网
MXKHTML5中文学习网 - HTML5先行者学习网

解决上述的异常,将webview操作放在主线程中即可。MXKHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
MXKHTML5中文学习网 - HTML5先行者学习网
webView.post(new Runnable() {MXKHTML5中文学习网 - HTML5先行者学习网
    @OverrideMXKHTML5中文学习网 - HTML5先行者学习网
    public void run() {MXKHTML5中文学习网 - HTML5先行者学习网
        webView.loadUrl(YOUR_URL).MXKHTML5中文学习网 - HTML5先行者学习网
    }MXKHTML5中文学习网 - HTML5先行者学习网
});MXKHTML5中文学习网 - HTML5先行者学习网
MXKHTML5中文学习网 - HTML5先行者学习网

(责任编辑:)
推荐书籍
推荐资讯
关于HTML5先行者 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助