1. 交互方式总结

1Android与JS通过WebView互相调用方法,实际上是:

  • Android去调用JS的代码
  • JS去调用Android的代码
    二者沟通的桥梁是WebView

    对于Android调用JS代码的方法有2种: 
    1. 通过WebViewloadUrl() 
    2. 通过WebViewevaluateJavascript()

    对于JS调用Android代码的方法有3种: 
    1. 通过WebViewaddJavascriptInterface()进行对象映射 
    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方式】的更多相关文章

  1. 原生+H5开发之:Android webview配置

    在上一篇文章Android 原生开发.H5.React-Native开发特点,我们可以了解到三种Android开发方式的区别和优缺点.[Android开发:原生+H5]系列的文章,将主要讲解Andro ...

  2. Android 与H5之间的js交互

    之前项目做过一些Android和Html5之间js交互方面的东西,今天有时间就总结一下: 一.为什么要进行js交互: 为了方便原生开发和Html之间数据传递,在静态页面的情况下可以改变原生开发的页面: ...

  3. 鸿蒙系统应用开发之JS实现一个简单的List

    在之前的文章鸿蒙应用开发之怎么更好的远程连接手表模拟器做调试里我运行了一个穿戴设备的应用,利用JS UI实现了一个最简单的HelloWorld. 今天我打算在智慧屏设备上利用豆瓣音乐的接口数据实现一个 ...

  4. android webView开发之js调用java代码示例

    1.webView设置 webView.getSettings().setJavaScriptEnabled(true);//设置支持js webView.addJavascriptInterface ...

  5. H5开发之Eclipes 编码乱码问题

    1.编码不对 a.对某文件或某工程更改编码: 鼠标移到工程名或文件名,右键->Properties->Resource->Text file enCoding ->更改编码(G ...

  6. Android开发之UI的编程方式创建

    我们知道,android中一个activity对应一个xml的UI配置文件,除了用xml文件配置的方式创建用户界面外,还可以使用代码编程的方式来创建一个用户界面.如果用户界面需要在运行过程中动态生成的 ...

  7. (一〇七)iPad开发之modal的切换方式与展示方式

    在iPad上modal有四种切换方式,分别是竖直进入(由下到上,默认方式).水平翻转.淡入淡出. 属性要设置在将要modal出来的控制器上: /* typedef NS_ENUM(NSInteger, ...

  8. 微信小游戏开发之JS面向对象

    //游戏开发之面向对象 //在js的开发模式中有两种模式:函数式+面向对象 //1.es5 // 拓展一:函数的申明和表达式之间的区别 // 函数的申明: // function funA(){ // ...

  9. Android开发之5大布局方式详解

    Android中常用的5大布局方式有以下几种: 线性布局(LinearLayout):按照垂直或者水平方向布局的组件. 帧布局(FrameLayout):组件从屏幕左上方布局组件. 表格布局(Tabl ...

随机推荐

  1. KKT条件和拉格朗日乘子法详解

    \(\frac{以梦为马}{晨凫追风}\) 最优化问题的最优性条件,最优化问题的解的必要条件和充分条件 无约束问题的解的必要条件 \(f(x)\)在\(x\)处的梯度向量是0 有约束问题的最优性条件 ...

  2. 6.Python3标准库--数学运算

    ''' 作为一种通用的变成语言,Python经常用来解决数学问题.它包含一些用于管理整数和浮点数的内置类型,这很适合完成一般应用中可能出现的基本数学运算. 而标准库中包含一些用于满足更高级需求的模块. ...

  3. shell中的变量与eval(转)

    原文链接:http://www.361way.com/shell-eval-variable/4957.html shell 中经常会用到变量的嵌套的情况.比如,单个或多个变量的值作为变量名,再对该变 ...

  4. 当想把html element里面的text提取出来可以试着用正则

    var a='123<span>456</span><span class="active">789</span>'; a.repl ...

  5. Linux命令之ip命令

    linux的ip命令和ifconfig类似,但前者功能更强大,并旨在取代后者.使用ip命令,只需一个命令,你就能很轻松地执行一些网络管理任务.ifconfig是net-tools中已被废弃使用的一个命 ...

  6. tensorflow运行出现错误 : ImportError: Could not find 'cudart64_90.dll'.

    安装 tensorflow-gpu 版本后,需要安装相应的 CUDA 和 cuDNN 注意版本问题:tensorflow-gpu 1.7以及之后的版本要安装 CUDA 8.0 以上的版本,tf 1.7 ...

  7. JS原生Date类型方法的一些冷知识

    ps:由于Date()是js原生函数,不同浏览器的解析器对其实现方式并不同,所以返回值也会有所区别.本文测试未特别申明浏览器的情况下,均是指win7 x64+chrome 44.0.2403.155 ...

  8. 【WPF】Bitmap Effect制作圆角加渲染TextBox

    <Window.Resources> <ControlTemplate x:Key="txtTemplate" TargetType="{x:Type ...

  9. vue表格导入

    <input id="upload" type="file" @change="importfxx(this)"  accept=&q ...

  10. 2017/11/22 Leetcode 日记

    2017/11/22 Leetcode 日记 136. Single Number Given an array of integers, every element appears twice ex ...