原生+H5开发之:js交互【location方式】
1. 交互方式总结
1Android与JS通过WebView互相调用方法,实际上是:
- Android去调用JS的代码
- JS去调用Android的代码
二者沟通的桥梁是WebView
对于Android调用JS代码的方法有2种:
1. 通过WebView的loadUrl()
2. 通过WebView的evaluateJavascript()对于JS调用Android代码的方法有3种:
1. 通过WebView的addJavascriptInterface()进行对象映射
2. 通过WebViewClient的shouldOverrideUrlLoading ()方法回调拦截 url
3. 通过WebChromeClient的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt()消息 2.1 Android通过WebView调用 JS 代码
mWebView =(WebView) findViewById(R.id.webview);
mWebView.loadUrl("file:///android_asset/javascript.html");LocationActivity.this.webView.post(() -> LocationActivity.this.webView.evaluateJavascript(
"javascript:locationDidChange('" + LocationActivity.this.locationString + "')", value -> {
// 此处为 js 返回的结果
}));2.2 JS通过WebView调用 Android 代码
方式2:通过
WebViewClient的方法shouldOverrideUrlLoading ()回调拦截 url<!DOCTYPE html>
<html> <head>
<meta charset="utf-8">
<title>Carson_Ho</title> <script>
function callAndroid(){
/*约定的url协议为:js://webview?arg1=111&arg2=222*/
document.location = "js://webview?arg1=111&arg2=222";
}
</script>
</head> <!-- 点击按钮则调用callAndroid()方法 -->
<body>
<button type="button" id="button1" onclick="callAndroid()">点击调用Android代码</button>
</body>
</html>private class MyWebViewClient extends WebViewClient { @TargetApi()
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return this.shouldOverrideUrlLoading(view, request.getUrl().toString());
} @Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// 步骤2:根据协议的参数,判断是否是所需要的url
// 一般根据scheme(协议格式) & authority(协议名)判断(前两个参数)
// 假定传入进来的 url = "js://webview?arg1=111&arg2=222"(同时也是约定好的需要拦截的)
Uri uri = Uri.parse(url);
// 如果url的协议 = 预先约定的 js 协议
// 就解析往下解析参数
if (uri.getScheme().equals("js")) {
// 如果 authority = 预先约定协议里的 webview,即代表都符合约定的协议
// 所以拦截url,下面JS开始调用Android需要的方法
if (uri.getAuthority().equals("webview")) {
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + uri.getQueryParameter("tel")));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
LocationActivity.this.startActivity(intent);
} else if (uri.getAuthority().equals("location")) { LocationActivity.this.webView.post(() -> LocationActivity.this.webView.evaluateJavascript(
"javascript:locationDidChange('" + LocationActivity.this.locationString + "')", value -> {
// 此处为 js 返回的结果
})); } else if (uri.getAuthority().equals("toast")) { Toast.makeText(LocationActivity.this, uri.getQueryParameter("info"), Toast.LENGTH_SHORT).show();
} else if (uri.getAuthority().equals("takePhoto")) { photoIdent = uri.getQueryParameter("ident");
openPopupWindow();
} else if (uri.getAuthority().equals("takeVideo")) {
/***************************** 录制视频 ***********************************/
EventBus.getDefault().post(new VideoIdentEvent(uri.getQueryParameter("ident")));
Intent intent = new Intent(LocationActivity.this, VideoActivity.class);
intent.putExtra(VideoActivity.VIDEO_IDENT, uri.getQueryParameter("ident"));
startActivity(intent);
} else if (uri.getAuthority().equals("playVideo")) {
/***************************** 播放视频 ***********************************/
startActivity(new Intent(LocationActivity.this, VideoPlayerActivity.class).putExtra("path",
uri.getQueryParameter("path")));
} else if (uri.getAuthority().equals("takeAudio")) {
/******************************** 录制音频 ********************************/
dialogShow(uri.getQueryParameter("ident"));
} else if (org.apache.commons.lang3.StringUtils.equals(uri.getAuthority(), "userLogin")) {
/******************************** 登录 ********************************/
String username = uri.getQueryParameter("username");
if (TextUtils.isEmpty(username)) {
return true;
} JPushInterface.setAlias(LocationActivity.this, username.hashCode(), username); String account = uri.getQueryParameter("yx_username");
String password = uri.getQueryParameter("yx_password"); chatFragment.startImLogin(username, account, password);
} else if (org.apache.commons.lang3.StringUtils.equals(uri.getAuthority(), "userLogout")) {
/******************************** 退出 ********************************/
chatFragment.logout(); finish();
} else if (org.apache.commons.lang3.StringUtils.equals(uri.getAuthority(), "playAudio")) {
/***************************** 播放视频 ***********************************/
MediaActivity.start(LocationActivity.this, uri.getQueryParameter("path"));
} return true;
} return false;
}这种方式的优点就是不存在漏洞,并且稳定

原生+H5开发之:js交互【location方式】的更多相关文章
- 原生+H5开发之:Android webview配置
在上一篇文章Android 原生开发.H5.React-Native开发特点,我们可以了解到三种Android开发方式的区别和优缺点.[Android开发:原生+H5]系列的文章,将主要讲解Andro ...
- Android 与H5之间的js交互
之前项目做过一些Android和Html5之间js交互方面的东西,今天有时间就总结一下: 一.为什么要进行js交互: 为了方便原生开发和Html之间数据传递,在静态页面的情况下可以改变原生开发的页面: ...
- 鸿蒙系统应用开发之JS实现一个简单的List
在之前的文章鸿蒙应用开发之怎么更好的远程连接手表模拟器做调试里我运行了一个穿戴设备的应用,利用JS UI实现了一个最简单的HelloWorld. 今天我打算在智慧屏设备上利用豆瓣音乐的接口数据实现一个 ...
- android webView开发之js调用java代码示例
1.webView设置 webView.getSettings().setJavaScriptEnabled(true);//设置支持js webView.addJavascriptInterface ...
- H5开发之Eclipes 编码乱码问题
1.编码不对 a.对某文件或某工程更改编码: 鼠标移到工程名或文件名,右键->Properties->Resource->Text file enCoding ->更改编码(G ...
- Android开发之UI的编程方式创建
我们知道,android中一个activity对应一个xml的UI配置文件,除了用xml文件配置的方式创建用户界面外,还可以使用代码编程的方式来创建一个用户界面.如果用户界面需要在运行过程中动态生成的 ...
- (一〇七)iPad开发之modal的切换方式与展示方式
在iPad上modal有四种切换方式,分别是竖直进入(由下到上,默认方式).水平翻转.淡入淡出. 属性要设置在将要modal出来的控制器上: /* typedef NS_ENUM(NSInteger, ...
- 微信小游戏开发之JS面向对象
//游戏开发之面向对象 //在js的开发模式中有两种模式:函数式+面向对象 //1.es5 // 拓展一:函数的申明和表达式之间的区别 // 函数的申明: // function funA(){ // ...
- Android开发之5大布局方式详解
Android中常用的5大布局方式有以下几种: 线性布局(LinearLayout):按照垂直或者水平方向布局的组件. 帧布局(FrameLayout):组件从屏幕左上方布局组件. 表格布局(Tabl ...
随机推荐
- 清理oracle的用户中的日志垃圾以及修改sys用户的密码
清理oracle的用户中的日志垃圾1.进入:/opt/oracle/product/11g/network/admin目录2.注释掉listener.ora文件中的TRACE_LEVEL_LISTEN ...
- Linux系统调优及安全设置
1.关闭SELinux #临时关闭 setenforce 0 #永久关闭 vim /etc/selinux/config SELINUX=disabled 2.设定运行级别为3 #设定运行级别 vim ...
- BeanUtils封装对象时一直提示ClassNotFoundException:org.apache.commons.beanutils.BeanUtils
导包明明正确了,依赖包也全都导对了,还是出错. 困扰了3天. 后来看到这篇博文,https://blog.csdn.net/yanshaoshuai/article/details/81624890 ...
- 浅谈BeanUtils的拷贝,深度克隆
1.BeanUtil本地简单测试在项目中由于需要对某些对象进行深度拷贝然后进行持久化操作,想到了apache和spring都提供了BeanUtils的深度拷贝工具包,自己写了几个Demo做测试,定义了 ...
- cin关闭同步[转]
很多人会说cin的速度比scanf慢很多, 其实不然. cin慢的原因主要在于默认cin与stdin总是保持同步, 这一步是消耗时间大户. 只需要加上ios::sync_with_stdio(fals ...
- 利用Fidder工具抓取App数据包
第一步:下载神器Fiddler,下载链接: http://fiddler2.com/get-fiddler 下载完成之后,傻瓜式的安装一下了! 第二步:设置Fiddler打开Fiddler, ...
- 【Mac】Chrome中添加截图扩展插件FireShot方法
FireShot是一款可以使用谷歌浏览器快速捕捉当前网页中元素的chrome截图插件,在谷歌浏览器中安装FireShot插件以后可以对网页中整个屏幕或者是网页的部分视图进行截图操作,在截图之后用户还可 ...
- Hibernate (开源对象关系映射框架)
一.基本介绍1.它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm(对象关系映射)框架,hibernate可以自动生成SQL语句,自动执行: Hibern ...
- Jquery 官网下载流程
选中解压版本,然后把ctrl+s保存另存为他的min版本
- 洛谷P1403 [AHOI2005] 约数研究 [数论分块]
题目传送门 约数研究 题目描述 科学家们在Samuel星球上的探险得到了丰富的能源储备,这使得空间站中大型计算机“Samuel II”的长时间运算成为了可能.由于在去年一年的辛苦工作取得了不错的成绩, ...