详解 WebView 与 JS 交互传值问题

随着混合开发模式比较流行,很多时候,我们需要在原生的基础上,使用 WebView 加载网页,这样控制更加方便。今天我们来看看,如何将 Java 对象 和 List 集合传值给 JS 调用。

如何将 Java 对象实例传值给 JS

其实将我们在 Android 原生中将 Java 对象实例传值给 JS 承认并且可以使用的对象,方法非常简单。我们来举个例子。

html 文件

我们在本地写了一个 html 文件,放在 assets 目录中。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>测试</title>
  <h1 id="name" ></h1>
  <h1 id="age"></h1>
  <h1 id="sex"></h1>
  <script>
  // Android需要调用的方法
  function callJS(){
   document.getElementById("age").innerHTML=person.getAge();
   document.getElementById("name").innerHTML=person.getName();
   document.getElementById("sex").innerHTML=person.getSex();
  }
  </script>
</head>
</html>

看到 callJS() 函数中的 person 了吗?它就是我们传值进行的 Java 对象实例。直接就可以使用,获取了年龄,名字,和性别属性。那我们该如何声明该对象,才会被 JS 所承认呢?

Java 对象

来,看看,我们是如何创建 Person 这个实体类的。代码如下:

package com.loonggg.wedswebview;

import android.webkit.JavascriptInterface;

/**
 * Created by loonggg on 2017/5/11.
 */
public class Person {
  private String name;
  private String age;
  private String sex;

  @JavascriptInterface
  public String getAge() {
    return age;
  }

  public void setAge(String age) {
    this.age = age;
  }

  public void setSex(String sex) {
    this.sex = sex;
  }

  @JavascriptInterface
  public String getSex() {
    return sex;
  }

  @JavascriptInterface
  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

}

看到我们实体类 Person 中每个get方法的上面有一个 @JavascriptInterface 的注解了吗?它的意思就是告诉 JS ,这个可以用,所以我们在 Html 文件中,使用 person.get()对应的方法,可以获取到内容。

在 WebView 上是这样传值的:

webView.loadUrl("file:///android_asset/test_object.html");
final Person p = new Person();
p.setName("loonggg");
p.setAge("28");
p.setSex("男");

wv.addJavascriptInterface(p, "person");

wv.loadUrl("javascript:callJS()");

wv.addJavascriptInterface(p, “person”); 的意思就是注入 Java 对象 p 给 webview 为 person,在 JS 调用的时候,对应的就是 person 。

wv.loadUrl(“JavaScript:callJS()”);这句话的意思就是:调用JS中的方法 callJS()函数方法。

Java List如何传给 JS 呢?

其实按道理来说,是不可以将List集合直接传值给 JS 使用,但是既然对象可以传值,JS 可以调用 java 对象,也可以调用 Android 中的方法,那我们就一拆分的形式传过去。

Html 文件

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>测试</title>
  <h1 id="name" ></h1>
  <h1 id="age"></h1>
  <h1 id="sex"></h1>

  <h1>List传值测试</h1>
  <h1 id="name1" ></h1>
  <h1 id="age1"></h1>
  <h1 id="sex1"></h1>
  <script>
  // Android需要调用的方法
  function callJS(){
   document.getElementById("age").innerHTML=person.getAge();
   document.getElementById("name").innerHTML=person.getName();
   document.getElementById("sex").innerHTML=person.getSex();
  }

  function callListJS(){
   document.getElementById("age1").innerHTML=window.javatojs.getPersonObject(0).getAge();
   document.getElementById("name1").innerHTML=window.javatojs.getPersonObject(0).getName();
   document.getElementById("sex1").innerHTML=window.javatojs.getPersonObject(0).getSex()
  }
  </script>
</head>
</html>

拆分传值

如何拆分呢?就是在JS中调用 Android中的方法,里面可以按照索引返回集合中的对象,然后再获取对象中的属性。代码如下:

 /**
   * 该方法将在js脚本中,通过window.javatojs.....()进行调用
   *
   * @return
   */
  @JavascriptInterface
  public Person getPersonObject(int index) {
    return list.get(index);
  }

  @JavascriptInterface
  public int getSize() {
    return list.size();
  }

   list.add(p);
   wv.addJavascriptInterface(this, "javatojs");

   wv.loadUrl("javascript:callListJS()");

整个Acitvity中所有的代码

public class MainActivity extends AppCompatActivity {
  private WebView wv;
  private List<Person> list = new ArrayList<Person>();

  @SuppressLint("JavascriptInterface")
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    wv = new WebView(this);
    setContentView(wv);
    WebSettings ws = wv.getSettings();
    ws.setJavaScriptEnabled(true);
    ws.setUseWideViewPort(true);//适应分辨率
    ws.setLoadWithOverviewMode(true);

    wv.loadUrl("file:///android_asset/test_object.html");
    final Person p = new Person();
    p.setName("loonggg");
    p.setAge("28");
    p.setSex("男");
    wv.addJavascriptInterface(p, "person");

    list.add(p);
    wv.addJavascriptInterface(this, "javatojs");

    wv.setWebViewClient(new WebViewClient() {
      @Override
      public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        wv.loadUrl("javascript:callJS()");
        wv.loadUrl("javascript:callListJS()");
      }
    });
  }

  /**
   * 该方法将在js脚本中,通过window.javatojs.....()进行调用
   *
   * @return
   */
  @JavascriptInterface
  public Person getPersonObject(int index) {
    return list.get(index);
  }

  @JavascriptInterface
  public int getSize() {
    return list.size();
  }

}

效果图

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • Android编程使用WebView实现与Javascript交互的方法【相互调用参数、传值】

    本文实例讲述了Android编程使用WebView实现与Javascript交互的方法.分享给大家供大家参考,具体如下: Android中可以使用WebView加载网页,同时Android端的Java代码可以与网页上的JavaScript代码之间相互调用. 效果图: (一)Android部分: 布局代码: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&qu

  • 详解 WebView 与 JS 交互传值问题

    随着混合开发模式比较流行,很多时候,我们需要在原生的基础上,使用 WebView 加载网页,这样控制更加方便.今天我们来看看,如何将 Java 对象 和 List 集合传值给 JS 调用. 如何将 Java 对象实例传值给 JS 其实将我们在 Android 原生中将 Java 对象实例传值给 JS 承认并且可以使用的对象,方法非常简单.我们来举个例子. html 文件 我们在本地写了一个 html 文件,放在 assets 目录中. <!DOCTYPE html> <html>

  • Android中webview与JS交互、互调方法实例详解

    Android中webview与JS交互.互调方法实例详解 前言: 对于试水的功能,一般公司都会采用H5的方式来开发,可以用很少的资源与很短的项目工期来完成. 但许多情况下,H5页面会需要一些原生持有的一些如用户信息之类的数据,一些交互也需要调用原生的,如toast之类要保持同一个手机风格一致的交互行为.这个时候就需要能够让JS主动调用原生的方法来进行操作或者获取数据.或者是原生调用JS的方法在H5加载的时候传递一些参数. 对于原生调用JS的方法 我们需要实现一个WebViewClient,在这

  • Android WebView与JS交互全面详解(小结)

    Android 和 H5 都是移动开发应用的非常广泛.市面上很多App都是使用Android开发的,但使用Android来开发一些比较复杂附属类,提示性的页面是得不偿失的.而H5具有开发速度快,更新不用依赖于App的更新,只需要服务端更新相应的页面即可,所以,App和H5页面相结合就显得尤为重要.而android和H5都不可能每次都是独立存在的,而是相互影响也相互的调用,获取信息等,例如,H5页面要获取App中的用户的基本信息,或者App端要操作H5页面等,下面来看看这两是怎么交互的 目录 1.

  • 详解vue组件之间相互传值的方式

    概述 我们都知道 Vue 作为一个轻量级的前端框架,其核心就是组件化开发.Vue 就是由一个一个的组件构成的,组件化是它的精髓,也是最强大的功能之一.而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用. 但在实际项目开发过程中,我们需要访问其他组件的数据,这样就就有了组件通信的问题.在 vue 中组件之间的关系有:父子,兄弟,隔代.针对不同的关系,怎么实现数据传递,就是接下来要讲的. 一.父组件向子组件传值 即父组件通过属性的方式向子组件传值,子组件通过 props 来接收

  • 详解从vue的组件传值着手观察者模式

    观察者模式 首先,提到观察者模式,这不禁让我想到了MVVM,MVVM架构模式感觉用到了观察者的思想. 我们还是按照惯例,了解一下什么是观察者模式 观察者模式,类似发布订阅模式,完成这个动作首先最少得有两个不同的对象,或者多个对象,他更像是一种一队多的依赖关系,也就是一种对象的状态发生改变,与其相关所有的对象的状态都会发生改变:比如说朋友圈这个功能,一个人可能有上百个好友,当我发布一条朋友圈后,所有和我成为好友的人都会看见这个朋友圈,当另一个人点赞后,所有你的好友其他点赞的人也会收到通知,这很像观

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

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

  • 详解在Vue.js编写更好的v-for循环的6种技巧

    在VueJS中,v-for循环是每个项目都会使用的东西,它允许您在模板代码中编写for循环. 在最基本的用法中,它们的用法如下. <ul> <li v-for='product in products'> {{ product.name }} </li> </ul> 但是,在本文中,我将介绍六种方法来使你的 v-for 代码更加精确,可预测和强大. 让我们开始吧. 1.始终在v-for循环中使用key 首先,我们将讨论大多数Vue开发人员已经知道的常见最佳做

  • 详解阿里Node.js技术文档之process模块学习指南

    模块概览 process是node的全局模块,作用比较直观.可以通过它来获得node进程相关的信息,比如运行node程序时的命令行参数.或者设置进程相关信息,比如设置环境变量. 环境变量:process.env 使用频率很高,node服务运行时,时常会判断当前服务运行的环境,如下所示 if(process.env.NODE_ENV === 'production'){ console.log('生产环境'); }else{ console.log('非生产环境'); } 运行命令 NODE_EN

  • 详解c#与js的rsa加密互通

    ASN.1 抽象语法表示(标记)ASN.1(Abstract Syntax Notation One )一种数据定义语言,描述了对数据进行表示.编码.传输和解码的数据格式.网络管理系统中的管理信息库(MIB).应用程序的数据结构.协议数据单元(PDU)都是用ASN.1定义的. 可以理解为ASN.1是对密钥结构定义的一种规范 密钥结构类型 PKCS#1 RSAPublicKey ::= SEQUENCE { modulus INTEGER, -- n publicExponent INTEGER

  • 详解在node.js中require方法的加载规则

    require 方法的加载规则 优先从缓存中加载 核心模块 路径形式的模块 第三方模块 一.优先从缓存中加载 main.js:执行加载a.js模块 require('./a') a.js:执行加载b.js模块,并输出a被加载了 require('./b') console.log('a.js 被加载了') b.js:输出b被加载了 console.log('b.js 被加载了') 结果: 可以看出:main去加载a.js,然后a在去加载b.js过程中,并没有打印两次 a.js被加载,Node会直

随机推荐