Android中实现WebView和JavaScript的互相调用详解

前言

很多复杂的UI界面,在Android中需要配合大量xml代码和java代码实现,而使用HTML5可以非常轻松的实现出来,而且具有很好的跨平台特性,让我们不必为了多个平台而重写代码,H5学习成本也较低,上手快。虽然从目前来说H5在Android系统中的速度可能还欠佳一些,但相信随着手机的性能不断的提高,这些问题都会被解决

使用H5开发Android的UI界面,最重要的就是如何实现Js代码和Java代码之间的互相调用了

在讲解之前,让我们先把项目跑起来

效果图:

准备好index.html文件,将它放入Android工程下的assets文件夹中:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <title>JSTest</title>
 <script src="app.js"></script>
</head>
<body>
<table border="1" width="100%" id="table" cellspacing="0">
 <tr>
  <td width="50%" align="center">姓名</td>
  <td width="50%" align="center">电话</td>
 </tr>
</table>
<hr>
<input id="jsinput">
<Button onclick="getMessage()">js传值给Toast</Button>
</body>
</html>

JavaScript的代码我单独写在一个js文件中了,把app.js文件也放入assets文件夹中:

function getMessage(){
 var message = document.getElementById("jsinput");
 contact.showToast(message.value);
}
function addPerson(persons){
 var personObjs = eval(persons);
 var table = document.getElementById("table");
 for(var i=0; i < personObjs.length; i++){
  var tr = table.insertRow(table.rows.length);
  var td1 = tr.insertCell(0);
  td1.align = "center";
  var td2 = tr.insertCell(1);
  td2.align = "center";

  td1.innerHTML = personObjs[i].name;
  td2.innerHTML = personObjs[i].phone;
 }
}

最后就是Java代码

public class MainActivity extends AppCompatActivity {
 private WebView mWebView;
 private Button mJsMethodBtn;
 private JsObject jsobj;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  mJsMethodBtn = (Button) findViewById(R.id.btn_js_method);
  mWebView = (WebView) findViewById(R.id.web_view);
  mWebView.loadUrl("file:///android_asset/index.html");
  WebSettings setting = mWebView.getSettings();
  setting.setJavaScriptEnabled(true);
  setting.setDefaultTextEncodingName("utf-8");
  jsobj = new JsObject();
  mWebView.addJavascriptInterface(jsobj, "contact");
  mJsMethodBtn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    // 添加一个联系人
    jsobj.addPerson();
   }
  });
 }

 private class JsObject {
  // 此方法被js调用
  @JavascriptInterface
  public void showToast(String message) {
   Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
  }
  // 在Web页面增加一个联系人
  public void addPerson() {
   String json = "[{\"name\":\"zwt\",\"phone\":\"15949999999\"}]";
   mWebView.loadUrl("javascript:addPerson('" + json + "')");
  }
 }
}

还有布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="#EED5B7"
 android:orientation="vertical">

 <WebView
  android:id="@+id/web_view"
  android:layout_width="match_parent"
  android:layout_height="360dp"/>

 <Button
  android:id="@+id/btn_js_method"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:text="调用js方法"/>
</LinearLayout>

一、JavaScript调用Android中的方法

这里实现的场景是点击Web页面中的Button,把input中输入的数据传递给Android系统,并通过Toast显示出来

对应的js代码:

function getMessage(){
 var message = document.getElementById("jsinput");
 contact.showToast(message.value);
}

对应的java代码:

// 此方法被js调用
@JavascriptInterface
public void showToast(String message) {
 Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
}

其中的“contact”其实指的就是我们在java代码中定义的JsObject类

他俩通过以下方法实现绑定:

mWebView.addJavascriptInterface(jsobj, "contact");

第一个参数传入的是一个java对象,第二参数是指定对应的js里调用该类时需要使用的自定义别名,这个方法的作用就是将一个Java对象和JavaScript联系起来

这里需要注意个问题,在SDK17以上的版本中,google为了安全考虑,只允许js调用带有@JavascriptInterface注解的Java方法,所以我们要给被js调用的java方法前加上@JavascriptInterface注解

二、Android调用JavaScript中的方法

用户点击Android中的Button控件后,传一个json数据给JavaScript方法,js解析json数据后添加一个新的联系人显示在Web页面上

对应的js代码:

function addPerson(persons){
 var personObjs = eval(persons);
 var table = document.getElementById("table");
 for(var i=0; i < personObjs.length; i++){
  var tr = table.insertRow(table.rows.length);
  var td1 = tr.insertCell(0);
  td1.align = "center";
  var td2 = tr.insertCell(1);
  td2.align = "center";
  td1.innerHTML = personObjs[i].name;
  td2.innerHTML = personObjs[i].phone;
 }
}

对应的java代码:

// 在Web页面增加一个联系人
public void addPerson() {
 String json = "[{\"name\":\"zwt\",\"phone\":\"15949999999\"}]";
 mWebView.loadUrl("javascript:addPerson('" + json + "')");
}

想要调用JavaScript中的某个方法,使用以下方法的标准格式就可以了:

mWebView.loadUrl("javascript:xxxMethod()");

“xxxMethod()”指的是JavaScript中的某个方法,如需调用其它方法,只要把后面的xxxMethod()替换成js中对应的方法就好

三、常见问题

1.Android与js互调不成功

  • 给WebView的setJavaScriptEnabled方法设置为true,使其允许js代码执行
  • 在API高于17的版本上,需要被js调用的java方法前加上@JavascriptInterface
  • 检查js中的别名是否写错,调用java方法时类的别名,一定要是mWebView.addJavascriptInterface(jsobj, “contact”);里面定义的别名

2.网页的alert弹不出

需要重写WebChromeClient中的onJsAlert()方法

mWebView.setWebChromeClient(new WebChromeClient() {
 @Override
 public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
  return super.onJsAlert(view, url, message, result);
 }
});

如果需要把web页面的alert弹出框替换成Android的AlertDialog,可以在onJsAlert()方法里进行重写,并设置return为true

3.Js调用java方法修改UI界面不成功

只要明白这一点:js调用的java方法,其实是运行在另外一个子线程WebViewCoreThread中
测试一下:把以下语句分别放在Activity的onCreate()方法里和被js调用的java方法中

Log.e(TAG, "运行线程name->" + Thread.currentThread().getName());

当onCreate执行时运行的log:

运行线程name->main

当JsObject类中的方法运行时的log:

运行线程name->WebViewCoreThread

很明显,子线程不允许修改主线程UI,所以我们想通过js调用java代码直接修改UI界面的做法是不被允许的
如果需要修改,可以通过Handler机制去解决

4.如何让手机的返回键跳到上一个Web页面

如果不对手机系统的返回键进行处理,那么我们按返回键会直接关闭当前Activity,而不会回到上一个Web页面
解决这个问题,我们可以重写Activity中的onBackPressed()方法:

@Override
public void onBackPressed() {
 super.onBackPressed();
 if (mWebView.canGoBack()) {
  mWebView.goBack();
 } else {
  finish();
 }
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

您可能感兴趣的文章:

  • android中webview控件和javascript交互实例
  • android webview中使用Java调用JavaScript方法并获取返回值
  • Android WebView使用方法详解 附js交互调用方法
  • 解析Android中webview和js之间的交互
  • Android中 webView调用JS出错的解决办法
  • Android webview与js交换JSON对象数据示例
  • Android WebView上实现JavaScript与Java交互
  • Android中在WebView里实现Javascript调用Java类的方法
  • 基于Android中Webview使用自定义的javascript进行回调的问题详解
  • Android中WebView与Js交互的实现方法
(0)

相关推荐

  • Android中在WebView里实现Javascript调用Java类的方法

    为了方便网页和Android应用的交互,Android系统提供了WebView中JavaScript网页脚本调用Java类方法的机制.只要调用addJavascriptInterface方法即可映射一个Java对象到JavaScript对象上. 1.映射Java对象到JavaScript对象上 复制代码 代码如下: mWebView = (WebView) findViewById(R.id.wv_content); mWebView.setVerticalScrollbarOverlay(tr

  • android中webview控件和javascript交互实例

    当我们要实现丰富的图文混排效果的时候,我们一般会使用webview,这是一个功能十分强大的的控件,来看看官方的解释: 复制代码 代码如下: A View that displays web pages. This class is the basis upon which you can roll your own web browser or simply display some online content within your Activity. It uses the WebKit

  • 解析Android中webview和js之间的交互

    1.android中利用webview调用网页上的js代码.Android 中可以通过webview来实现和js的交互,在程序中调用js代码,只需要将webview控件的支持js的属性设置为true,,然后通过loadUrl就可以直接进行调用,如下所示:mWebView.getSettings().setJavaScriptEnabled(true);mWebView.loadUrl("javascript:test()"); 2. 网页上调用android中java代码的方法在网页中

  • Android WebView使用方法详解 附js交互调用方法

    目前很多Android app都内置了可以显示web页面的界面,会发现这个界面一般都是由一个叫做WebView的组件渲染出来的,学习该组件可以为你的app开发提升扩展性. 先说下WebView的一些优点: --可以直接显示和渲染web页面,直接显示网页 --webview可以直接用html文件(网络上或本地assets中)作布局 --和JavaScript交互调用 一.基本使用 首先layout中即为一个基本的简单控件: <WebView android:id="@+id/webView1

  • 基于Android中Webview使用自定义的javascript进行回调的问题详解

    先说为什么需要讨论这个问题. 现在很多的手机应用,都可能会直接嵌入一个web页面.这样做的好处:一个是功能更新方便,维护起来容易,只需要维护服务器的页面即可,不需要更新客户端:另一个是功能通用,不仅android可以用,ios也可以用,symbian也可以直接用. 那为什么现在很多手机应用并不做成web方式的呢?原因很多.一个是现阶段web方式展现能力相对较弱,如果对于应用的美观程度要求比较高,就无法使用web方式:一个是web方式速度相对较慢,用户体验会受一些影响:一个是现阶段流量还是相对宝贵

  • Android webview与js交换JSON对象数据示例

    最近几个项目的测试结果,Android无法主动通过调用 webview.loadUrl("javascript:"+callbackFunction+"('"+data+"')"); 这种方式将jsonobject类型的data传给js,因为js那边得到就是一个string的对象. 与此同时,js主动调用android的对象方式,android也无法返回给js一个jsonobject,需要js做一下转换,例如: Android 代码: 复制代码

  • Android中WebView与Js交互的实现方法

    获取WebView对象 调用WebView对象的getSettings()方法,获取WebSettings对象 调用WebSettings对象的setJavaScriptEnabled()方法,设置js可用,参数:布尔值 在判断是否支持js的时候,不要用alert(),默认不起作用,可以先用document.write()测试 调用WebView对象的addJavascriptInterface(obj, interfaceName)方法,添加js接口,参数:Object对象,String接口名

  • Android中 webView调用JS出错的解决办法

    问题 webView调用JS出错. 复制代码 代码如下: class TestJS {         ......         public TestJS(){         }                 public void save(String data){                        webView.loadUrl("javascript: alert(" + data +")");         }         ..

  • android webview中使用Java调用JavaScript方法并获取返回值

    在android平板上用webview打开一个网页,调用里面的javascript方法,同时相互传参. 网上例子很少啊,基本都不能获取返回值,贴一个自己最后调试完的代码如下: Java: 复制代码 代码如下: protected void onCreate(Bundle savedInstanceState) { ........ x = (WebView)this.findViewById(R.id.webView_viewTable); x.setScrollBarStyle(View.SC

  • Android WebView上实现JavaScript与Java交互

    其实webview加载资源的速度并不慢,但是如果资源多了,当然就很慢.图片.css .js .html这些资源每个大概需要10-200ms ,一般都是30ms就ok了.不过webview是必须等到全部资源都完成加载,才会进行渲染的,所以加载的速度很重要!从Google上我们了解到,webview加载页面的顺序是:先加载html,然后从里面解析出css.js文件和页面上的图片资源进行加载.如果webkit的缓存里面有,就不加载.加载完这些资源之后,就进行css的渲染和js的执行.Css的渲染一般不

随机推荐