原生+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 ...
随机推荐
- 78.PL和PS通过BRAM交互共享数据
本篇文章目的是使用Block Memory进行PS和PL的数据交互或者数据共享,通过zynq PS端的Master GP0端口向BRAM写数据,然后再通过PS端的Mater GP1把数据读出来,将结果 ...
- Linux 查看网卡流量【转】
我的系统式RHEL5. 在linux下,查看网卡流量的方法有很多.下面先记录几个,和他们的大概用法.已被以后之需. 一:iptraf 一个很不错的工具.RHEL5 iso自带有,我 ...
- 夜神安卓模拟器adb命令详解
https://www.yeshen.com/faqs/H15tDZ6YW 一.如何找到adb? 安装夜神安卓模拟器后,电脑桌面会有"夜神模拟器"的启动图标,鼠标右键--打开文件所 ...
- 19.Remove Nth Node From End of List---双指针
题目链接 题目大意:删除单链表中倒数第n个节点.例子如下: 法一:双指针,fast指针先走n步,然后slow指针与fast一起走,记录slow前一个节点,当fast走到链表结尾,slow所指向的指针就 ...
- python是如何进行内存管理的?
Python内存管理机制 Python内存管理机制主要包括以下三个方面: 引用计数机制 垃圾回收机制 内存池机制 引用计数 举个例子说明引用是什么: 1 如上为一个简单的赋值语句,1就是对象,a就是引 ...
- C# 多线程多文件批量下载---子线程中更新UI 实例
代码1: using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;usi ...
- 可图性判定--Havel-Hakimi定理
两个概念 1.度序列 若把图G所有顶点的度数排成一个序列S,则称S为图G的度序列. 2.序列是可图的 一个非负整数组成的序列如果是某个无向图的度序列,则称该序列是可图的. Havel-Hakimi定理 ...
- 【严蔚敏】【数据结构题集(C语言版)】1.16 自大至小依次输出读入的三个整数X,Y,Z
#include <stdio.h> #include<stdlib.h> int main() { int x,y,z,temp; scanf("%d%d%d&qu ...
- jQuery 最简化实现
window.jQuery = (selector) => { let nodes = {}; if (typeof selector === 'string') { //是字符串 let te ...
- ElasticSearch部署文档(Ubuntu 14.04)
ElasticSearch部署文档(Ubuntu 14.04) 参考链接 https://www.elastic.co/guide/en/elasticsearch/guide/current/hea ...