在Android上怎样实现JAVA和JS交互

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Android上怎样实现JAVA和JS交互相关的知识,希望对你有一定的参考价值。

android的开发过程中、遇到一个新需求、那就是让Java代码和javascript代码进行交互、在ios中实现起来很麻烦、而在Android中相对来说容易、Android对这种交互进行很好的封装、其实可以很简单的用Java代码调用WebView中的js函数、也可以用WebView中的js来调用Android应用中的Java代码

一、网页的JS代码调用ANDROID中JAVA代码的方法

在网页中调用java代码、需要在webview控件中添加javascriptInterface

contentWebView = (WebView) findViewById(R.id.webview);

//启用javascript
contentWebView.getSettings().setJavaScriptEnabled(true);
contentWebView.addJavascriptInterface(this, "js对象名");

在Activity中定义一个要被js调用的方法、src为js传递过来的参数、如果没有不传也可以的。

public void jsFunction(final String str)

Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
runOnUiThread(new Runnable()
@Override
public void run()
//在里对Android应用的UI进行处理

);

在网页中、只需要像调用js方法一样、进行调用就可以

<a onClick="window.js对象名.jsFunction(´hello world´)" >

点击调用java代码并传递参数
</a>

二、ANDROID中JAVA代码调用网页的JS代码的方法

Java代码调用js并传参其实是通过WebView的loadUrl方法去调用的、只是参数url的写法不一样

// 无参数调用

contentWebView.loadUrl("javascript:javacalljs()");
// 传递参数调用
contentWebView.loadUrl("javascript:javacalljswithargs("
+ "´hello world´" + ")");

三、JAVA和JS交互注意事项

1、Java 调用 js 里面的函数、效率并不是很高、估计要200ms左右吧、做交互性很强的事情、这种速度很难让人接受、而js去调Java的方法、速度很快、50ms左右、所以尽量用js调用Java方法

2、Java 调用 js 的函数、没有返回值、调用就控制不到

3、Js 调用 Java 的方法、返回值如果是字符串、你会发现这个字符串是 native 的、转成 locale 的才能正常使用、使用 toLocaleString() 函数就可以、不过这个函数的速度并不快、转化的字符串如果很多、将会很耗费时间

4、网页中尽量不要使用jQuery、执行起来需要5-6秒、最好使用原生的js写业务脚本、以提升加载速度、改善用户体验

参考技术A 实现Java和js交互十分便捷。需要以下几步。
1. WebView开启JavaScript脚本执行
2. WebView设置供JavaScript调用的交互接口。
3. 客户端和网页端编写调用对方的代码。本回答被提问者采纳
参考技术B Java和js交互有以下一些特点:
  1.Java 调用 js 里面的函数,速度并不令人满意,大概一次一两百毫秒吧,如果要做交互性很强的事情,这种速度会让人疯掉的。而反过来就不一样了, js 去调 java 的方法,速度很快,基本上 40-50 毫秒一次。所以尽量用 js 调用 java 方法,而不是 java 去调用 js 函数。
  2.Java 调用 js 的函数,没有返回值,而 Js 调用 java 方法,可以有返回值。返回值可以是基本类型、字符串,也可以是对象。如果是字符串,有个很讨厌的问题,第 3 点我会讲的。如果是对象,这个对象会被转换为 js 的对象,直接可以访问里面的方法。但是我不推荐 java 返回给 js 的是对象,除非是必须。因为 js 收到 java 返回的对象,会产生一些交换对象,而如果这些对象的数量增加到了 500 或 600 以上,程序就会出问题。所以尽量返回基本数据类型或者字符串。
  3.Js 调用 Java 的方法,返回值如果是字符串,你会发现这个字符串是 native 的,不能对它进行一些修改操作,比如想对它 substr ,取不到。怎么解决呢?转成 locale 的。使用 toLocaleString() 函数就可以了。不过这个函数的速度并不快,转化的字符串如果很多,将会很耗费时间。
参考技术C   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);


  

  前端网页代码

  代码如下:

<html>
<script type="text/javascript">
function sayHello()
alert("Hello")


  function alertMessage(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

  注意
  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).

);

安卓中java和js如何交互

1、安卓中java和js如何交互

在Android上怎样实现JAVA和JS交互呢?Android的webview是基于webkit内核的,webview中集成了js与java互调的接口函数,通过addJavas criptInterface方法,可以将Java的类注册进webkit,给网页上的js进行调用,而且还可以通过loadUrl方法是给webkit传递一个URL,供浏览器来进行解析,实现Java和js交互。

要想运行网页上的js脚本,webview必须设置支持Javas cript。

2、安卓的MVC

 

  1) 视图层(View):一般采用XML文件进行界面的描述,使用的时候可以非常方便的引入。当然,如何你对Android了解的比较的多了话,就一定可以想到在Android中也可以使用JavaScript+HTML等的方式作为View层,当然这里需要进行Java和JavaScript之间的通信,幸运的是,Android提供了它们之间非常方便的通信实现。     

  2) 控制层(Controller):Android的控制层的重任通常落在了众多的Acitvity的肩上,这句话也就暗含了不要在Acitivity中写代码,要通过Activity交割Model业务逻辑层处理,这样做的另外一个原因是Android中的Acitivity的响应时间是5s,如果耗时的操作放在这里,程序就很容易被回收掉。

  3) 模型层(Model):对数据库的操作、对网络等的操作都应该在Model里面处理,当然对业务计算等操作也是必须放在的该层的。就是应用程序中二进制的数据。

3、如何看代码
eclipse项目:
首先看androidmanifest.xml
包名、应用名
4、

Another refresh project task is currently running for the project 

全部释义和例句>>另一个刷新项目任务是当前正在运行的项目

 

以上是关于在Android上怎样实现JAVA和JS交互的主要内容,如果未能解决你的问题,请参考以下文章

安卓中java和js如何交互

在android中怎样调用本地js文件里的方法并得到返回值

Android 利用WebViewJavascriptBridge 实现js和java的交互

Android 利用WebViewJavascriptBridge 实现js和java的交互

本地java代码和javascript进行交互(java和js互调)

Webview Android与js交互