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

如何实现

实现Java和js交互十分便捷。通常只需要以下几步。

1.WebView开启JavaScript脚本执行

2.WebView设置供JavaScript调用的交互接口。

3.客户端和网页端编写调用对方的代码。

本例代码

为了便于讲解,先贴出全部代码

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

}

}

}

前端网页代码

复制代码 代码如下:

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)

}

Java-Javascript Interaction In Android

调用示例

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() {

@Override

public void onReceiveValue(String value) {

Log.i(LOGTAG, "onReceiveValue value=" + value);

}});

}

输出结果

复制代码 代码如下:

I/MainActivity( 1432): onReceiveValue value=1

注意

1.上面限定了结果返回结果为String,对于简单的类型会尝试转换成字符串返回,对于复杂的数据类型,建议以字符串形式的json返回。

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

中文大意为

复制代码 代码如下:

警告:如果你的程序目标平台是17或者是更高,你必须要在暴露给网页可调用的方法(这个方法必须是公开的)加上@JavascriptInterface注释。如果你不这样做的话,在4.2以以后的平台上,网页无法访问到你的方法。

解决方法

1.将targetSdkVersion设置成17或更高,引入@JavascriptInterface注释

2.自己创建一个注释接口名字为@JavascriptInterface,然后将其引入。注意这个接口不能混淆。这种方式不推荐,大概在4.4之后有问题。

注,创建@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 调用js,Android中Java和JavaScript交互实例相关推荐

  1. java调用exe_Windows系统中Java调用cmd命令及执行exe程序的方法

    Java调用cmd命令,并输出显示信息: package com.anxin.cmd.test; import java.io.BufferedReader; import java.io.Input ...

  2. android java 调用js_android WebApp 集成方式怎么使用java调用js

    WebAPP集成,本地打包,有两种方式java js通信 1.DCloud插件模式,参考SDK DEMO的H5Plugin, Java:继承StandardFeature写接口. public cla ...

  3. java 调用 js性能_太快了,太变态了:什么会影响Java中的方法调用性能?

    java 调用 js性能 那么这是怎么回事? 让我们从一个简短的故事开始. 几周前,我提议对Java核心libs邮件列表进行更改 ,以覆盖当前final一些方法. 这刺激了一些讨论主题-其中之一是其中 ...

  4. Java调用JS,JS调用JAVA

    JAVA 调用 JS //Java端 //带参数的函数调用 final String exes = "cc.Global.setEcADVal('"+ var1 + "' ...

  5. python调用js库中的函数_Python 调用JS文件中的函数

    Python 调用JS文件中的函数 1.安装PyExecJS第三方库 2.导入库:import execjs 3.调用JS文件中的方法 Passwd = execjs.compile(open(r&q ...

  6. android jni java调用c,Android与JNI(一) ---- Java调用C 静态调用

    第一.通过eclipse新建一个工程名为HelloJni的android工程,并编译. 第二.右键工程-->Android Tools --> Add Native Support,出现如 ...

  7. android 连续调用js方法,Android的WebView中的JavascriptInterface:对JS的多次调用会导致死锁...

    这是我用过的整个Java代码.我将在下面更详细地解释... public class Test7 extends Activity { //debug private final static Str ...

  8. android 怎么调用js项目_APP逆向神器之Frida【Android初级篇】

    说到逆向APP,很多人首先想到的都是反编译,但是单看反编译出来的代码很难得知某个函数在被调用时所传入的参数和它返回的值,极大地增加了逆向时的复杂度,有没有什么办法可以方便地知道被传入的参数和返回值呢? ...

  9. android studio调用python,Android studio中编写Python代码-2

    Chaquopy 教程 Chaquopy Chaquopy的作用:使用Chaquopy在Android Studio添加Python环境,java和Python互调 目前调试后APP可以正常运行(20 ...

最新文章

  1. Win7 Vista下的输入法问题
  2. 斯坦福NLP笔记72 —— The Inverted Index
  3. 网络推广外包专员浅析货拉拉坠车事件后宣布整改增加录音录像功能
  4. python和java一样吗-python 和 java 的区别
  5. OpenCV 中值滤波
  6. android如何使用ios14组件,ios14小组件怎么添加 苹果ios14小组件添加使用教程
  7. centos非root用户创建用户_CentOS中用户和用户组管理
  8. linux sql 语句菜鸟,Linux安装mysql
  9. server 2008 mysql 报错 0xc000007b_这十个MySQL经典错误,99%的程序员一定遇到过!你呢?...
  10. python中颜色空间直方图_OpenCV—python 颜色空间(RGB,HSV,Lab)与 颜色直方图
  11. redhat multipath配置文件简要说明
  12. CSS选择器详解(转)
  13. 在Debian 6 安装pptpd ×××。
  14. 超像素分割算法(SLIC)
  15. SQLServer 2008 r2 安装图解
  16. 01web前端笔试试题
  17. 2016.4.5_基于nodejs的聊天室【笔记】
  18. Linux文件颜色与文件类型对应(白色、蓝色、红色、黄色、绿色 代表的意义。。。)
  19. PROGRESSIVE GROWING OF GANS FOR IMPROVED QUALITY, STABILITY, AND VARIATION(PGGAN)
  20. 日语五十音之平假音和片假音的巧记

热门文章

  1. 怎么写CORTEX在windows用arm-none-eabi-gcc编译时的makefile
  2. php get_token_all函数,pimcore getObjectByToken函数PHP对象注入漏洞
  3. ios 直播点赞_微信新版本更新:为视频号直播虚拟礼物,还提供连麦、美颜等功能...
  4. 安卓如何调出软键盘_智能汽车到底如何交互?小鹏用全场景语音给出了答案
  5. 「猜题第一篇」2019年大学生电子设计竞赛
  6. dns的服务器地址是多少当前位置,dns的服务器地址设置为多少
  7. splitpane如何设置竖条的宽度_页面中有间隔的方格布局如何完美实现?
  8. 广东外语外贸大学计算机考研,广东外语外贸考研难度,2021考研广东外语外贸大学MTI会挤破头很难吗?...
  9. linux二重进程,二叉树递归实现与二重指针
  10. oracle 叠加代码写法,利用st_geometry进行图形叠加分析