H5混合开发 js与java相互调用

来源:互联网 发布:鬼脚七淘宝搜索 编辑:程序博客网 时间:2024/05/08 06:42

介绍

  • 本篇主要介绍H5与android相互调用

1.Android中调用H5的js的实现

首先创建一个index页面

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">    <title>H5混合开发</title>    <script src="js/jquery.min.js"></script></head><body><p> 我是H5页面</p></body></html>

在android中初始化webview加载上面网页的url

public class AndroidH5Activity extends AppCompatActivity {    private WebView mWebview;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_android_h5);        initView();        //webview设置        setWebView();        //在线模板:调试模式,当页面发生改变,客户端不需要重新编译运行,把工程创建在Tomacat下        mWebview.loadUrl("http://10.0.3.2:8080/WebDemo/index.html");    }    private void setWebView() {        WebSettings settings = mWebview.getSettings();        //开启JS和android通信开关        settings.setJavaScriptEnabled(true);        //使用内置webview打开其他链接        mWebview.setWebViewClient(new WebViewClient() {            @Override            public void onPageStarted(WebView view, String url, Bitmap favicon) {                super.onPageStarted(view, url, favicon);            }            //页面加载完成回调方法            @Override            public void onPageFinished(WebView view, String url) {                super.onPageFinished(view, url);                //以json的方式传递数据 调用js方法: 对象.方法名(参数)                //mWebview.loadUrl("javascript:方法名(参数)");                //android 调用 js 代码                JSONObject json = new JSONObject();                try {                    json.put("name", "android");                    json.put("message", "你好H5,我是android!收到请回答!");                    //调用js代码                    mWebview.loadUrl("javascript:showMessage(" + json.toString() + ")");                } catch (JSONException e) {                    e.printStackTrace();                }            }        });        mWebview.setWebChromeClient(new WebChromeClient() {            //加载进度            @Override            public void onProgressChanged(WebView view, int newProgress) {                super.onProgressChanged(view, newProgress);            }            @Override            public void onReceivedTitle(WebView view, String title) {                super.onReceivedTitle(view, title);            }        });    }    private void initView() {        mWebview = (WebView) findViewById(R.id.webview);    }}

在上面webview初始化中mWebview.loadUrl(“javascript:showMessage(” + json.toString() + “)”);这行代码负责去调用js中的代码,主要方法名要与js中的方法名相同

H5中对android中的代码做出响应

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">    <title>H5混合开发</title>    <script src="js/jquery.min.js"></script></head><body><script>    //android调用js代码    var showMessage = function (json) {        alert(JSON.stringify(json));    };</script></body></html>

当跳转到H5界面就会显示以下内容

这里写图片描述

H5实现对Android的调用

首先在H5中写js调用android方法

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">    <title>H5混合开发</title>    <script src="js/jquery.min.js"></script>    <style>        button {            width: 100%;            height: 38px;            color: white;            border-style: none;            font-size: 20px;            border-radius: 6px;            background-color: #50b2ff;            margin-top: 10px;        }        button:active {            background-color: #2e87ff;        }    </style></head><body><button id="btn1">js主动调用安卓</button><script>    //统一管理js调用android方法    var invokeAndroid = function (json) {        //调用android方法        // window.映射字符串.方法名        window.jsInterface.invokeMethods(JSON.stringify(json));    };    //JS调用android代码    $("#btn1").on("click", function () {        console.log("H5页面点击了按钮一");        var json = {"name": "H5", "message": "你好!我是H5,收到!收到!", "action": "showToast"};        invokeAndroid(json);    });    //android调用js代码    var showMessage = function (json) {        alert(JSON.stringify(json));    };</script></body></html>

上面H5页面中是以一个按钮的点击形式,通过json字符串的形式传递给android客户端
window.jsInterface.invokeMethods(JSON.stringify(json));中的jsInterface是在android代码中定义的,下面会给出定义方式

public class AndroidH5Activity extends AppCompatActivity {    private WebView mWebview;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_android_h5);        initView();        //webview设置        setWebView();        //本地模板:为了优化WebView,正式上线可以使用,只要页面不经常改变,可以使用callback+本地模板,把工程创建在assets下        mWebview.loadUrl("file:///android_asset/WebDemo/index.html");        //在线模板:调试模式,当页面发生改变,客户端不需要重新编译运行,把工程创建在Tomacat下        // mWebview.loadUrl("http://10.0.3.2:8080/WebDemo/index.html");        //这是通信的桥梁类        JavaScriptMethods javaScriptMethods = new JavaScriptMethods(this, mWebview);        //设置H5和android通信接口:参数1-提供给js调用的对象,参数2-第1个参数的映射字符串(别名)        mWebview.addJavascriptInterface(javaScriptMethods, "jsInterface");    }    private void setWebView() {        WebSettings settings = mWebview.getSettings();        //开启JS和android通信开关        settings.setJavaScriptEnabled(true);        //使用内置webview打开其他链接        mWebview.setWebViewClient(new WebViewClient() {            @Override            public void onPageStarted(WebView view, String url, Bitmap favicon) {                super.onPageStarted(view, url, favicon);            }            //页面加载完成回调方法            @Override            public void onPageFinished(WebView view, String url) {                super.onPageFinished(view, url);                //以json的方式传递数据 调用js方法: 对象.方法名(参数)                //mWebview.loadUrl("javascript:方法名(参数)");                //android 调用 js 代码                JSONObject json = new JSONObject();                try {                    json.put("name", "android");                    json.put("message", "你好H5,我是android!收到请回答!");                    mWebview.loadUrl("javascript:showMessage(" + json.toString() + ")");                } catch (JSONException e) {                    e.printStackTrace();                }            }        });        mWebview.setWebChromeClient(new WebChromeClient() {            //加载进度            @Override            public void onProgressChanged(WebView view, int newProgress) {                super.onProgressChanged(view, newProgress);            }            @Override            public void onReceivedTitle(WebView view, String title) {                super.onReceivedTitle(view, title);            }        });    }    private void initView() {        mWebview = (WebView) findViewById(R.id.webview);    }}

定义android与H5之前的桥梁类

public class JavaScriptMethods {    private static final String TAG = "JavaScriptMethods";    private Activity mActivity;    private WebView mWebView;    private Handler mHandler = new Handler();    public JavaScriptMethods(Activity activity, WebView webView) {        mActivity = activity;        mWebView = webView;    }    /**     * 统一管理所有H5和安卓通信方法,相当于入口函数     */    // 自定义H5+android通信协议规则:为了安全    /*安全:android17以上,如果不加上该注解,H5无法调用安卓方法,谷歌为了安全,因为低版本js能够通过反射调用android系统功能*/    @JavascriptInterface    public void invokeMethods(String json) {        //解析动作字符串 js中定义的"action"        try {            JSONObject jsJSON = new JSONObject(json);            String action = jsJSON.optString("action");            Log.e(TAG, "invokeMethods: " + action);            if ("showToast".equals(action)) {                showToast(json);            }         } catch (JSONException e) {            e.printStackTrace();        }    }    private void showToast(String json) {        Toast.makeText(mActivity, "" + json, Toast.LENGTH_SHORT).show();    }}

不难看出桥梁类中是通过js中的方法,传递json字符串给客户端,然后通过json中的action字段的类型,来判断需要做什么操作
这里写图片描述

3.上面两种已经实现了android与H5的交互,下面callback的形式实现解耦,并且更安全

首先看index页面

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">    <title>H5混合开发</title>    <script src="js/jquery.min.js"></script>    <style>        button {            width: 100%;            height: 38px;            color: white;            border-style: none;            font-size: 20px;            border-radius: 6px;            background-color: #50b2ff;            margin-top: 10px;        }        button:active {            background-color: #2e87ff;        }    </style></head><body><button id="btn1">js主动调用安卓</button><button id="btn2">js callback式回调android</button><script>    //统一管理js调用android方法    var invokeAndroid = function (json) {        //调用android方法        // window.映射字符串.方法名        window.jsInterface.invokeMethods(JSON.stringify(json));    };    //JS调用android代码    $("#btn1").on("click", function () {        console.log("H5页面点击了按钮一");        var json = {"name": "H5", "message": "你好!我是H5,收到!收到!", "action": "showToast"};        invokeAndroid(json);    });    //JS调用android代码    $("#btn2").on("click", function () {        //js调用ajax获取服务器返回数据,但是有的公司客户端已经完成网络通信框架,这时候如果H5在写一套网络通信框架,        // 可以用callback避免H5编写过多代码        //1.先主动调用Android方法        var json = {"callback": "receiveData", "action": "getJSData"};        invokeAndroid(json);    });    var receiveData = function (json) {        //2.android 回调给 js ,        alert("接受到Android回传数据=" + JSON.stringify(json));    };    //android调用js代码    var showMessage = function (json) {        alert(JSON.stringify(json));    };</script></body></html>

这边主要是桥梁类做出了变化

public class JavaScriptMethods {    private static final String TAG = "JavaScriptMethods";    private Activity mActivity;    private WebView mWebView;    private Handler mHandler = new Handler();    public JavaScriptMethods(Activity activity, WebView webView) {        mActivity = activity;        mWebView = webView;    }    /**     * 统一管理所有H5和安卓通信方法,相当于入口函数     */    // 自定义H5+android通信协议规则:为了安全    /*安全:android17以上,如果不加上该注解,H5无法调用安卓方法,谷歌为了安全,因为低版本js能够通过反射调用android系统功能*/    @JavascriptInterface    public void invokeMethods(String json) {        //解析动作字符串 js中定义的"action"        try {            JSONObject jsJSON = new JSONObject(json);            String action = jsJSON.optString("action");            Log.e(TAG, "invokeMethods: " + action);            if ("showToast".equals(action)) {                showToast(json);            } else if ("getJSData".equals(action)) {                getJSData(json);            }        } catch (JSONException e) {            e.printStackTrace();        }    }    private void getJSData(String json) {        //模拟网络请求数据,以json的格式返回        Log.e(TAG, "getJSData: " + json);        JSONObject backJson = new JSONObject();        try {            //添加数据,这边是假数据,一般都是网络请求            backJson.put("name", "kevinyang");            backJson.put("age", "25");            backJson.put("address", "广东省深圳市");            backJson.put("email", "kevinyang0709@foxmail.com");            //解析获取js callback方法名            JSONObject jsJson = new JSONObject(json);            String callBack = jsJson.optString("callback");            callbackJs(callBack, backJson);        } catch (JSONException e) {            e.printStackTrace();        }    }    private void callbackJs(final String callback, final JSONObject json) {        mHandler.post(new Runnable() {            @Override            public void run() {                //回传酒店数据给H5页面:调用js方法,必须在主线程                //当前方式H5和按安卓耦合度过高,方法名写死                //mWebView.loadUrl("javascript:receiveData("+backJson.toString()+")");                //使用callback机制,解耦                mWebView.loadUrl("javascript:" + callback + "(" + json.toString() + ")");            }        });    }    private void showToast(String json) {        Toast.makeText(mActivity, "" + json, Toast.LENGTH_SHORT).show();    }}

这里写图片描述

0 0
原创粉丝点击