客户端相关知识学习(三)之Android原生与H5交互的实现
Android原生与H5交互的实现
H5调用原生的方式
方式可能有多种,根据开发经验,接触过两种方式。
方法一:Android向H5注入全局js对象,也就是H5调Android
1.首先对WebView进行初始化
|
WebSettings settings = webview.getSettings(); settings.setJavaScriptEnabled(true); //允许在WebView中使用js |
2.创建一个类JavaScriptMetod,专门用来给js提供可调用的方法
3.创建该类的构造方法,提供两个参数,WebView对象和上下文对象
|
private Context mContext; private WebView mWebView; public JavaScriptMethod(Context context, WebView webView) { mContext = context; mWebView = webView; } |
4.创建一个字符串常量,作为android与js通信的接口,即字符串映射对象
| public static final String JAVAINTERFACE = "javaInterface"; |
5.接下来就是创建给js调用的方法,方法的参数接收一个json字符串(注意:在Android4.2之后,为了提高代码安全性,方法必须使用注解@JavascriptInterface,否则无法调用)
|
@JavascriptInterface //andorid4.2(包括android4.2)以上,如果不写该注解,js无法调用android方法 public void showToast(String json){ Toast.makeText(context, json, Toast.LENGTH_SHORT).show(); } |
6.在WebView初始化代码中执行如下代码
|
//创建上面创建类的对象 JavaScriptMetod m = new JavaScriptMetod(this, webview); //其实就是告诉js,我提供给哪个对象给你调用,这样js就可以调用对象里面的方法 //第二个参数就是该类中的字符串常量 webview.addJavascriptInterface(m, JavaScriptMetod.javaInterface); 现在,在js中就可以调用JavaScriptMetod中的方法了,调用方式如下 //参数一般为json格式 var json = {"name":"javascript"}; //javaInterface是上面所说的字符串映射对象 window.javaInterface.showToast(JSON.stringify(json)); |
网络上介绍js与android原生交互的文章里,大部分都是上面这种方式,但是这种方式并不适用于ios,也就是说,window.javaInterface.showToast(JSON.stringify(json))这样的js代码并不适用于ios,如果用以上的方法,就得分别为android和ios各
写一套js代码。这样很显然是不太合理的,所以在实际开发中,一般都使用接下来的第二种方法。
方法二:H5发起自定义协议请求,Android拦截请求,再由Android调用H5中的回调函数
这种方法实现的思想是js发出一个url请求,并将所需的参数添加到该url中。android端通过webView.setWebViewClient()拦截url,解析url中携带的参数,并根据参数信息进行相应的操作。
1.与方法一相同,首先都需要对webview进行初始化
|
WebSettings settings = webview.getSettings(); settings.setJavaScriptEnabled(true); //允许在WebView中使用js |
2.首先看js中的代码是怎么写的
|
$("#showtoast").click(function () { var json = {"data": "I am a toast"}; window.location.href="protocol://android?code=toast&data="+JSON.stringify(json); }); $("#call").click(function () { var json = {"data": "10086"}; window.location.href="protocol://android?code=call&data="+JSON.stringify(json); }); |
这里定义两个点击事件,分别控制android显示toast和打电话的操作。其中,protocol://android为自定义的H5与android间的通信协议,与http请求进行区分。code规定了要进行的操作,data为传输的数据。
3.android中的代码
|
webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { /** * 通过判断拦截到的url是否含有pre,来辨别是http请求还是调用android方法的请求 */ String pre = "protocol://android"; if (!url.contains(pre)) { //该url是http请求,用webview加载url return false; } //该url是调用android方法的请求,通过解析url中的参数来执行相应方法 Map map = getParamsMap(url, pre); String code = map.get("code"); String data = map.get("data"); parseCode(code, data); return true; } }); |
其中,getParamsMap()方法从拦截到的url解析出code,data参数,parseCode()方法将根据不同的code进行相应的操作,代码如下:
|
private Map getParamsMap(String url, String pre) { ArrayMap queryStringMap = new ArrayMap<>(); if (url.contains(pre)) { int index = url.indexOf(pre); int end = index + pre.length(); String queryString = url.substring(end + 1); String[] queryStringSplit = queryString.split("&"); String[] queryStringParam; for (String qs : queryStringSplit) { if (qs.toLowerCase().startsWith("data=")) { //单独处理data项,避免data内部的&被拆分 int dataIndex = queryString.indexOf("data="); String dataValue = queryString.substring(dataIndex + 5); queryStringMap.put("data", dataValue); } else { queryStringParam = qs.split("="); String value = ""; if (queryStringParam.length > 1) { //避免后台有时候不传值,如“key=”这种 value = queryStringParam[1]; } queryStringMap.put(queryStringParam[0].toLowerCase(), value); } } } return queryStringMap; } private void parseCode(String code, String data) { if(code.equals("call")) { try { JSONObject json = new JSONObject(data); String phone = json.optString("data"); //执行打电话的操作,具体代码省略 PhoneUtils.call(this, phone); } catch (JSONException e) { e.printStackTrace(); } return; } if(code.equals("toast")) { try { JSONObject json = new JSONObject(data); String toast = json.optString("data"); Toast.makeText(this, toast, Toast.LENGTH_SHORT).show(); } catch (JSONException e) { e.printStackTrace(); } return; } } |
最后,特别说明一下shouldOverrideUrlLoading()方法的返回值问题,该方法的返回值有三种:
返回true,即根据代码逻辑执行相应操作,webview不加载该url;
返回false,除执行相应代码外,webview加载该url;
返回super.shouldOverrideUrlLoading(),点进父类中,我们可以看到,返回的还是false。
客户端相关知识学习(三)之Android原生与H5交互的实现的更多相关文章
- 客户端相关知识学习(十一)之Android H5交互Webview实现localStorage数据存储
前言 最近有一个需求是和在app中前端本地存储相关的,所以恶补了一下相关知识 webView开启支持H5 LocalStorage存储 有些时候我们发现写的本地存储没有起作用,那是因为默认WebVie ...
- 客户端相关知识学习(十二)之iOS H5交互Webview实现localStorage数据存储
前言 最近有一个需求是和在app中前端本地存储相关的,所以恶补了一下相关知识 webView开启支持H5 LocalStorage存储 有些时候我们发现写的本地存储没有起作用,那是因为默认WebVie ...
- 客户端相关知识学习(八)之Android“.9.png”
参考 Android中.9图片的含义及制作教程 .9.png Android .9.png 的介绍
- 客户端相关知识学习(六)之deeplink技术
Deeplink应用描述 Deeplink,简单讲,就是你在手机上点击一个链接之后,可以直接链接到app内部的某个页面,而不是app正常打开时显示的首页.不似web,一个链接就可以直接打开web的内页 ...
- 客户端相关知识学习(一)之混合开发,为什么要在App中使用H5页面以及应用场景、注意事项
混合开发 随着移动互联网的高速发展,常规的开发速度已经渐渐不能满足市场需求.原生H5混合开发应运而生,目前,市场上许多主流应用都有用到混合开发,例如支付宝.美团等.下面,结合我本人的开发经验,简单谈一 ...
- 客户端相关知识学习(九)之h5给app传递数据
方法一: 情况一: if (window.JdAndroid){ window.JdAndroid.setPayCompleted(); window.JdAndr ...
- 客户端相关知识学习(五)之什么是webView
webview是什么?作用是什么?和浏览器有什么关系? Android系统中内置了一款高性能 webkit 内核浏览器,在 SDK 中封装为一个叫做 WebView 组件也就是说WebView是一个基 ...
- 客户端相关知识学习(四)之H5页面如何嵌套到APP中
Android原生如何渲染H5页面 Android与 H5 的交互方式大概有以下 1 种: 利用WebView进行交互(系统API) iOS原生如何渲染H5页面 iOS 与 H5 的交互方式大概有以下 ...
- 客户端相关知识学习(二)之h5与原生app交互的原理
前言 现在移动端 web 应用,很多时候都需要与原生 app 进行交互.沟通(运行在 webview中),比如微信的 jssdk,通过 window.wx 对象调用一些原生 app 的功能.所以,这次 ...
随机推荐
- IDEA项目里Maven 的Plugins出现红线的解决方法
1.删除项目里的libraries(快捷键ctrl+shift+alt+s):Project Settings->Libraries,全选删除 2.删除之前项目产生的target 3.然后再in ...
- Linux上Python的安装升级
1.下载 cd /usr/local/src/ wget https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz 2.安装,在/usr/loc ...
- http1.1管线话 vs htttp2.0 多路复用
图中第一种请求方式,就是单次发送request请求,收到response后再进行下一次请求,显示是很低效的. 于是http1.1提出了管线化(pipelining)技术,就是如图中第二中请求方式,一次 ...
- yum源安装mysql数据库 添加密码
学习mysql数据库时,安装的问题一直很烦恼,linux的不同版本的安装方式都可能不同,这里是我学习时的一些总结.也是刚刚开始学习,大佬勿喷,谢谢啦!!! 1.查看是否已经安装 2.如果没安装 yum ...
- Java学习之==>Java8 新特性详解
一.简介 Java 8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级.Java 8是 Java 自 Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库. ...
- GCC 9.2 2019年8月12日 出炉啦
GNU 2019-08-12 发布了 GCC 9.2https://gcc.gnu.org/onlinedocs/9.2.0/ 有详细的说明 MinGW 上可用的 GCC 9.2 版本下载地址 [ m ...
- maven的基本使用
安装: 1.下载maven http://maven.apache.org/ 2.将maven包解压并放置到安装目录 3.添加环境变量M2_HOME,path当中添加;%M2_HOME%\bin; 4 ...
- JavaScript面向对象当中的几个概念
JS面向对象过程中的几个概念 前言 面向对象描述的是一种代码组织解构的形式,一种在软件中对真实世界中问题领域的建模方法. 下面将从理论层面来介绍下面向对象编程中一些常见的概念. 对象 所谓对象,本质上 ...
- ios 后台进程弹窗
// http://iphonedevwiki.net/index.php/CFUserNotification // https://kunnan.github.io/2018/05/14/com. ...
- HTTP及WEB框架简述
HTTP介绍 Hyper Text Transfer Protocol,超文本传输书协议,是万维网数据通信的基础,规定了请求和响应标准. HTTP工作原理 HTTP 请求以及响应的步骤 客户端连接到W ...