Android中Native和H5交互
1.概述
时至今日,H5的跨平台性越发凸显优势,一套代码适配android、ios,既能减少开发成本,又便于更新与维护.但是native的性能体验也确实更佳,尤其体现在复杂界面和频繁变化的界面上.事实上,移动平台native+h5的开发模式不是什么新鲜事了,各种框架层出不穷,主要目的就是为了使native与h5交互更加便捷高效,而在Android中必然需要WebView作为载体来展示H5内容和进行交互.
2.交互方式
- 传统的JSInterface:使用Android原生的javascriptInterface来进行js和java的通信.
Native Invoke Js
WebSettings webSettings = webView.getSettings();
//打通js通道 WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JsInterface(), "android");
//然后通过WebView的addJavascriptInterface方法去注入一个自定义的interface。
public class JsInterface {
@JavascriptInterface
public void showToast(String toast) {
Toast.makeText(MainActivity.this, toast, Toast.LENGTH_SHORT).show(); log("show toast success");
}
public void log(final String msg){
webView.post(new Runnable() {
@Override
public void run() {
webView.loadUrl("javascript: log(" + "'" + msg + "'" + ")");
}
});
}
}
webView.addJavascriptInterface(new JsInterface(), "android");
webView.loadUrl("file:///android_asset/interact.html");@JavascriptInterface 是为了修复4.2版本之前的addjavascriptInterface接口引起的漏洞,这个漏洞曾导致恶意网页通过Js方法遍历刚刚通过addjavascriptInterface注入进来的类的所有方法从中获取到getClass方法,然后通过反射获取到Runtime对象,进而调用Runtime对象的exec方法执行一些操作.于是,交互如果按照这种方式的话,就得区分4.2之前与之后. Js Invoke Native
function showToast(toast){
javascript:android.showToast(toast); //这里的android是上面java代码命名的
}
function log(msg){ console.log(msg); } - JSBridge的方式:其实就是通过重写WebView中WebChromeClient类的onJsPrompt()方法来进行js和java的通信。
对WebView熟悉的话,肯定知道Js中对应的
window.alert()、window.confirm()、window.prompt()这三个方法的调用在WebChromeClient中都有对应的回调方法,分别为:onJsAlert()、onJsConfirm()、onJsPrompt(),对于它们传入的message,都可以在相应的回调方法中接收到,所以,对于Js调Native方法, 可以借助这个信道,和前端协定好一段特定规则的message,这个规则中应至少包含这些信息:所调用Native方法所在类的类名
所调用Native的方法名
Js调用Native方法所传入的参数基于这些信息,定义一个自己的协议。比如规定sheme,path等等。比如:
scheme://host:port/path?query对应的协定
prompt传入message的格式为:jsbridge://class:port/method?params
这样,前端和app端协商好后,前端需要通过Js调用Native方法来获取一些信息或功能,就只需要按照协议的格式把需要调用的类名、方法名、参数放入对应得位置即可,而 会在onJsPrompt方法中接收到,所以根据与前端协定好的协议来进行解析, 可以用一个Uri来包装这段协议,然后通过Uri:getHost、getPath、getQuery方法获取对应的类名,方法名,参数数据,最后通过反射来调用指定类中指定的方法.(port的作用是为了标识Js中的回调function,当Js调用Native方法时,会得到本次调用的port号)
自动生成port和绑定function回调的Js代码如下:
generatePort: function () {
|
数据的返回格式为Json字符串,基本格式为:
resultData = {
|
所以符合Js调用的Native方法格式为:
public static void ***(WebView webView, JSONObject data, JsCallback callback) {
|
判断Js调用的方法是否符合该格式的代码为,符合则存入一个Map中供Js调用:
private void putMethod(Class<?> clazz) {
|
对于有返回值的方法,并不需要设置它的返回值,因为方法的结果最后是通过JsCallback.invokeJsCallback来进行对Js层的回调.
看图:
UrlRouter:UrlRouter是一个通过url来让前端唤起native页面的框架。不过,如果协议定义的合理,它可以让前端,Android和iOS三端有一个高度的统一,十分方便。
通过WebViewClient类的shouldOverrideUrlLoading方法去拦截前端写的url,发现如果是符合定义的UrlRouter协议的话,就跳转到相应的页面。
eg.前端一个按钮<input type="button" value="login" onclick="javascript:location.href='http://www.baidu.com/'">
java代码中这样:
@Override |
这种方式没怎么用过,也就不细说了.
3.总结
H5用Webview加载的方式,往往还涉及到WebView的各种安全性、兼容性的问题,再比如易OOM,Webview许多方法并不按正常时机加载;这些坑都是需要踩过填过之后才能积累经验的.上述3种方式,都有自己的适用场景,比如个别页面需要加载h5首推第一种,app中有大量的h5交互那么就直接用第二种吧,对于一些平台统一的特殊要求的话就用UrlRouter的方式了.
Android中Native和H5交互的更多相关文章
- Native与H5交互的一些解决方法
一. 原生代码中直接加载页面 1. 具体案例 加载本地/网络HTML5作为功能介绍页 2. 代码示例 //本地 -(void)loadLocalPage:(UIWebView*)webVi ...
- Android 中 js 和 原生交互
Android中的WebView 中加载的URL 默认是在手机浏览器中加载的,我们可以覆盖这种默认的动作,让网页在WebView中打开.通过设置WebView的WebViewClent 达到这个效果. ...
- Android WebView 基本设置与H5 交互
mWebView.setDrawingCacheEnabled(true); WebChromeClient webChromeClient = new WebChromeClient(); mWeb ...
- 深入分析:Android中app之间的交互(二,使用ComponentName)
在前一篇相关主题的博文中我们了解了如何使用Action来启动当前应用之外的Activity处理我们的业务逻辑,在本篇笔记中我在简单介绍一下使用ComponentName来与当前应用之外的应用进行交互. ...
- 深入分析:Android中app之间的交互(一,使用Action)
在我们开发Android App应用的时候,有些需求需要我们启动其他的App来处理一些逻辑,例如我们需要根据一个地址来调用系统或者相关的地图Map App,这样我们不用在自己的App中编写相应的功能, ...
- Android中WebView与H5的交互,Native与JS方法互调
项目中经常用到WebView与H5的交互,一个是H5调本地方法,一个是本地调H5方法,在此记录一下. 首先,启用JS支持 //启用js支持 webSettings.setJavaScriptEnabl ...
- Android 中Java和JavaScript交互入门
如何实现JavaScript 和java 交互 实现Java和js交互十分便捷.通常只需要以下几步. WebView开启JavaScript脚本执行 WebView设置供JavaScript调用的交互 ...
- Android中Java和JavaScript交互
Android提供了一个很强大的WebView控件用来处理Web网页,而在网页中,JavaScript又是一个很举足轻重的脚本.本文将介绍如何实现Java代码和Javascript代码的相互调用. 如 ...
- cordova混合开发:Android中native调用javascript
今天学习怎么在java中调用javascript方法,做个记录: 第一种方式,这个最简单: loadUrl("javascript:func1()"); 要注意要在devicere ...
随机推荐
- 在浏览器中输入url地址 -> 显示主页的过程
-来自<图解HTTP> 最近在进行前端面试方面的一些准备,看了网上许多相关的文章,发现有一个问题始终绕不开: 在浏览器中输入URL到整个页面显示在用户面前时这个过程中到底发生了什么.仔细思 ...
- CodeForces 738C Road to Cinema
二分答案. 油量越多,显然通过的时间越少.可以二分找到最小的油量,可以在$t$时间内到达电影院. 一个油箱容量为$v$的车通过长度为$L$的路程需要的最小时间为$max(L,3*L-v)$.计算过程如 ...
- Java数组(int为例)
Java数组(int为例) 定义:相同数据类型的数据的组合,是一种引用类型,是一个对象,存在堆里. 数组初始化:int[] scores1 = new int[]{72,90,59};//静态初始化: ...
- 【js学习】js连接RabbitMQ达到实时消息推送
js连接RabbitMQ达到实时消息推送 最近在自己捯饬一个网站,有一个功能是需要后端处理完数据把数据发布到MQ中,前端再从MQ中接收数据.但是前端连接MQ又成了一个问题,在网上搜了下资料,点进去一篇 ...
- ES5 Object.defineProperty 方法
先看一个例子: var o = {}; o.a = 1; // 等待于: Object.defineProperty(o, 'a', { value: 1, writable: true, confi ...
- mtk预装apk 方案公司内置预装apk
mtk预装apk 方案公司内置预装apk 韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha == MTK 预知第三方的APK 流程_yua ...
- [USACO 2018 Feb Gold] Tutorial
Link: USACO 2018 Feb Gold 传送门 A: $dp[i][j][k]$表示前$i$个中有$j$个0且末位为$k$的最优解 状态数$O(n^3)$ #include <bit ...
- AC自动机及KMP练习
好久都没敲过KMP和AC自动机了.以前只会敲个kuangbin牌板子套题.现在重新写了自己的板子加深了印象.并且刷了一些题来增加自己的理解. KMP网上教程很多,但我的建议还是先看AC自动机(Trie ...
- 【动态规划】Gym - 101201A - Alphabet
题意:一个字符串被定义为“alphabetical”,当且仅当它能够删除一些字符,变成“ab...yz”,给你一个只由小写字母组成的字符串,问你最少插入几个字母,使它变成“alphabetical”的 ...
- uboot如何检测XC2440是从Nand或Nor启动
转:http://blog.chinaunix.net/uid-22030783-id-3347621.html 在XC2440开发板上做uboot从nandflash启动时,需要检测硬件启动方式,启 ...