原生+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 ...
随机推荐
- linux系统分区参考
UPDATE: update is used to download package information from all configured sources. UPGRADE: upgrad ...
- 64_s1
SAASound-3.2-17.fc26.i686.rpm 13-Feb-2017 22:13 27650 SAASound-3.2-17.fc26.x86_64.rpm 13-Feb-2017 23 ...
- localhost或127.0.0.1或192.168.1.*被转到129129.com上的问题
系统启动里会有个httpd的apache程序在运行,自启禁用掉后.windows下有个apache文件夹,干掉就可以. 个别GHOST XP程序里面会装这种流氓程序.
- Windows Phone 8/Windows 8 启动第三方应用程序并传递参数
需要被其他应用启动的第三方应用需要注册protocol association,当一个应用程序启动一个特殊的URI的时候,那么注册了这个protocol的程序会自动启动,并且可以通过这个特殊的URI将 ...
- Linux下的各类文件
.a文件是静态链接库文件.所谓静态链接是指把要调用的函数或者过程链接到可执行文件中,成为可执行文件的一部分.当多个程序都调用相同函数时,内存中就会存在这个函数的多个拷贝,这样就浪费了宝贵的内存资源.. ...
- 取消cp确认
使用cp -r -f 强制覆盖拷贝命令时,每一个文件都需要认为的键入“Y”进行确认 可以通过取消同名cp的定义,命令如下unalias cp
- yii2联表查询
我们用实例来说明这一部分 表结构 现在有客户表.订单表.图书表.作者表, 客户表Customer (id customer_name) 订单表Order (id order_ ...
- AC日记——825G - Tree Queries
825G - Tree Queries 思路: 神题,路径拆成半链: 代码: #include <cstdio> #include <cstring> #include < ...
- int类中的方法(二)
25.__pos__(self,*args,**kwargs) def __pos__(self, *args, **kwargs): # real signature unknown &qu ...
- 【转载】OpenMAXIL介绍与其体系
1 OpenMAX IL介绍与其体系 这一部分的文档描述 OpenMAX IL的特性与体系. 1.1 OpenMAX IL 简述 OpenMAX IL 软件接口层定义了一套API,用于访问系统中的组件 ...