原生+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 ...
随机推荐
- 使用迭代法穷举1到N位最大的数
这是何海涛老师剑指offer上面第12题,这题首先注意不能使用整数int型作为操作对象,因为N很大时明显会溢出.这种大数据一般都是使用的字符串来表示. 直接法就是:1.针对字符串的加法,涉及循环进位及 ...
- [006] largest_common_substring
[Description] Given two different strings, find the largest successive common substring. e.g. str1[] ...
- 190.Reverse Bits---位运算
题目链接:https://leetcode.com/problems/reverse-bits/description/ 题目大意:将数值的二进制反转. 法一(借鉴):由于是无符号32位整型,当二进制 ...
- 19.Remove Nth Node From End of List---双指针
题目链接 题目大意:删除单链表中倒数第n个节点.例子如下: 法一:双指针,fast指针先走n步,然后slow指针与fast一起走,记录slow前一个节点,当fast走到链表结尾,slow所指向的指针就 ...
- java基础16 捕获、抛出以、自定义异常和 finally 块(以及关键字:throw 、throws)
1.异常的体系 /* ------|Throwable:所有异常和错误的超类 ----------|Error(错误):错误一般用于jvm或者硬件引发的问题,所以我们一般不会通过代码去处理错误的 -- ...
- Denoise Autoencoder简单理解
自编码器通过学习隐含特征来表达原始数据,那什么是denoise autoencoder呢? 关于Autoencoder参考:http://blog.csdn.net/on2way/article/de ...
- mac 安装mongodb与常用操作
1.安装 brew update brew install mongodb 2.启动mongo mongod --config /usr/local/etc/mongod.conf 3.启动 mong ...
- Hilite代码高亮工具
在用<有道云笔记>等软件时候,软件自身不提供代码高亮功能,对于需要记录code的学习笔记,视觉效果丢失. 有很多在线工具能用来代码高亮,比如oschina就有代码高亮页面用于着色. 但是我 ...
- SQL Server 数据库优化剖析
一.SQL Profiler 事件类 Stored Procedures\RPC:Completed TSQL\SQL:BatchCompleted 事件关键字段 EventSequence.Even ...
- 第 17 章 使用API
在本章中,我们将学习如何编写一个独立的程序,并对其获取的数据进行可视化.这个程序将使用Web应用编程接口(API)自动请求网站的特定信息而不是整个网页,再对这些信息进行可视化.由于这样编写的程序始终使 ...