Android-WebView与本地HTML (互调)

此篇博客是基于,上两篇博客Android-WebView与本地HTML (HTML调用-->Java的方法) , Android-WebView与本地HTML (Java调用--->HTML的方法) ;实现的一个综合实用案例

contacts.xml(HTML + JavaScript):

<!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>Web页面</title>


        <style type="text/css">
            html,body{
                width:100%;
                height:100%;
                padding:0px;
                margin:0px;
            }
            div.contact{
                margin:3px;
                position:relative;
                text-align: center;
                width:100%;
                height:40px;
                background-color:#e0dede;
            }
        </style>

        <script type="text/javascript">
            //保存模板html代码
            var template;

            //让java调用,生成联系人数据
            function show(arr){
                for(var i=0;i<arr.length;i++){
                    var innerHtml = document.body.innerHTML;
                    //利用模板替换生成每条数据
                    var row = template;
                    row = row.replace('name',arr[i].name);
                    row = row.replace('amount',arr[i].amount);
                    row = row.replace('phone',arr[i].phone);
                    row = row.replace('phone',arr[i].phone);
                    //将html拼接到body标签中
                    document.body.innerHTML = innerHtml+row;
                }
            }

            //初始化并且调用showcontacts去java请求数据
            function initContacts(){
                template = document.body.innerHTML;
                document.body.innerHTML = "";
                contact.showcontacts();
            }

            //按钮点击 时调用java的call
            function call(phone){
                contact.call(phone);
            }

            //页面加载时调用
            // window.onload = initContacts();

        </script>

    </head>

    <body onload="initContacts()">

        <!-- 模板项 -->
        <div class="contact">
            <span style="position:absolute;left:5px">name</span>
            <span style="position:absolute;top:20px;left:5px;font-size: 15px">amount</span>
            <span style="position:relative;top:5px;">phone</span>
            <button style="position:absolute;top:5px;right:5px" onclick="call('phone')">拨号</button>
        </div>

    </body>

</html>

描述实体Bean对象:

package cn.h5.java_and_html_call.bean;

public class ContactInfo {

    private String name;
    private String amount;
    private String phone;
    
    
    public ContactInfo() {
        super();
        // TODO Auto-generated constructor stub
    }
    
    
    public ContactInfo(String name, String amount, String phone) {
        super();
        this.name = name;
        this.amount = amount;
        this.phone = phone;
    }


    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAmount() {
        return amount;
    }
    public void setAmount(String amount) {
        this.amount = amount;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    
    
}

描述获得数据的服务对象:

package cn.h5.java_and_html_call.service;

import java.util.ArrayList;
import java.util.List;

import cn.h5.java_and_html_call.bean.ContactInfo;

public class ContactService {

    /**
     * 获取联系人的数据
     * @return
     */
    public List<ContactInfo> getContacts(){
        List<ContactInfo> contactInfos = new ArrayList<ContactInfo>();
        contactInfos.add(new ContactInfo("刘备", "10000000", "13900123456"));
        contactInfos.add(new ContactInfo("关羽", "2000000",  "18676868789"));
        contactInfos.add(new ContactInfo("张飞", "6000000",  "18900888888"));
        contactInfos.add(new ContactInfo("曹操", "13000000", "18000888888"));
        return contactInfos;
    }
}

Activity:

package cn.h5.java_and_html_call;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.List;

import cn.h5.R;
import cn.h5.java_and_html_call.bean.ContactInfo;
import cn.h5.java_and_html_call.service.ContactService;

public class MainActivity extends Activity {

    private ContactService service;
    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main5);
        service = new ContactService();

        /**
         * 你可以把webview看成一个浏览器,webview里面有一个插件,可以把一个java对象传递给webview的插件,
         * 当插件得到这个对象之后,就可以让网页里面的 javascript代码对这个java对象进行调用
         */
        webView = findViewById(R.id.webview);

        /**
         * 加载本地的 contacts.html 文件
         */
        webView.loadUrl("file:///android_asset/contacts.html");

        /**
         * webview默认是不能够执行javascript
         * 以下代码是设置允许webview能够执行javascript代码
         */
        webView.getSettings().setJavaScriptEnabled(true);

        /**
         *  把Java对象传递给WebView的插件
         *  让JavaScript调用 ---> Java ContactPlugin类中的 方法
         */
        webView.addJavascriptInterface(new ContactPlugin(),"contact" );

    }

    /**
     * 此ContactPlugin类中的方法,和JavaScript定义的一致
     * 目的是为了让JavaScript调用 --> ContactPlugin类中的方法
     */
    private final class ContactPlugin{

        /**
         * contacts.html 被加载就会 调用showcontacts方法来获得JSON数据 给 javascript:show(" + json + ")
         *
         * 注意:初始化数据,由JavaScript调用,
         *      获得数据后 转换为JSON并且调用JavaScript的show方法,
         *      把数据给 JavaScript的show方法,然后HTML就把列表数据展示出来了
         */
        @JavascriptInterface
        public void showcontacts(){
            Log.d("@@@", "showcontacts 被JavaScript页面加载的时候 调用了");
            try {
                List<ContactInfo> contacts = service.getContacts();
                JSONArray jsonArray = new JSONArray();
                for(ContactInfo info:contacts){
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("name", info.getName());
                    jsonObject.put("amount", info.getAmount());
                    jsonObject.put("phone", info.getPhone());
                    jsonArray.put(jsonObject);
                }
                final String json = jsonArray.toString();

                // Log.d("@@@", "json=======" + json);

                /**
                 * webView.loadUrl("javascript:show(" + json + ")");
                 * 注意:像这种方法不能写在这里,否则没效果一直阻塞的,打印不了:json=======后
                 * 解决方案:
                 *  需要加入runOnUiThread,才能解决此问题;
                 *  这个问题解决了两个小时 才发现是这里的问题,开始一直以为是html/js有问题
                 */
                // webView.loadUrl("javascript:show(" + json + ")");

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        /**
                         * Android WebView执行----> javascript代码
                         * Java调用----> JavaScript的show方法 把这些列表JSON数据,给JavaScript的show方法,然后HTML就把列表数据展示出来了
                         */
                        webView.loadUrl("javascript:show(" + json + ")");
                    }
                });


                Log.d("@@@", "json=======后");

            } catch (Exception e) {
                e.printStackTrace();

                Log.d("@@@", "e.ttt:" + e.toString());
            }
        }

        /**
         * 点击HTML列表上的电话号码后,此方法被JavaScript调用
         * 让JavaScript调用 打电话
         * @param phone
         */
        @JavascriptInterface
        public void call(String phone){
            Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phone));
            startActivity(intent);
        }
    }
}

activity的布局:

<?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:orientation="vertical">

    <!--
       定义WebView
           1.WebView可以展现处理本地的HTML相关;
           2.WebView可以展现处理网络的HTML相关;
           3.WebView可以制作自定义浏览器;
           ....
    -->
    <WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></WebView>

</LinearLayout>

执行结果:

 

猜你喜欢

转载自www.cnblogs.com/android-deli/p/10338704.html