之前一篇文章WebView使用解析(一)之基本用法我讲过了WebView与JS交互的方式,JS调用Java代码主要是通过对象注入的方式实现的,即使用addJavascriptInterface。而JAVA调用JS代码则是通过javascript:伪协议来实现的,即javascript:methodName(params……)。

但是这种交互方式存在着不少问题:

  • 1、Java 调用 js 里面的函数,效率并不是很高,估计要200ms左右,做交互性很强的事情这种速度很难让人接受。而js去调Java的方法,速度很快,50ms左右,所以尽量用js调用Java方法。
  • 2、Java 调用 js 的函数,没有返回值,调用了就控制不到了。
  • 3、Js 调用 Java 的方法,返回值如果是字符串,你会发现这个字符串是 native 的,转成 locale 的才能正常使用,使用 toLocaleString() 函数就可以了,不过这个函数的速度并不快、转化的字符串如果很多、将会很耗费时间。
  • 4、网页中尽量不要使用jQuery,执行起来需要5-6秒,最好使用原生的js写业务脚本,以提升加载速度、改善用户体验。
  • 5、Android4.2以下的系统存在着webview的js对象注入漏洞。

这里我给大家介绍另外一种Native与webview的交互方式,采用scheme的方式。

URL scheme

URI与Uri

URI位置在java.net.URI,显然是Java提供的一个类。而Uri位置在android.net.Uri,是由Android提供的一个类。所以初步可以判断,Uri是URI的“扩展”以适应Android系统的需要。

概述

android中的scheme是一种页面内跳转协议,是一种非常好的实现机制,通过定义自己的scheme协议,可以非常方便跳转app中的各个页面;通过scheme协议,服务器可以定制化告诉App跳转那个页面,可以通过通知栏消息定制化跳转页面,可以通过H5页面跳转页面等。

应用场景

客户端应用可以向操作系统注册一个URL Scheme,该scheme用于从浏览器或其他应用中启动本应用,通过scheme协议来跳转到相应的APP界面,比如商品详情,活动详情,商家详情等等界面。也可以执行某些指定动作,如完成支付等。也可以在应用内部通过H5页面来直接跳转APP某个界面。

URL Scheme应用场景分为以下4种:

  • 服务器下发跳转路径,客户端根据服务器下发跳转路径跳转相应的页面
  • H5页面点击描点,根据描点具体跳转路径APP端跳转具体的页面
  • APP端收到服务器端下发的PUSH通知栏消息,根据消息的点击跳转路径跳转相关页面

格式

[scheme:][//host:port][path][?query][#fragment]

URL Scheme 属性分为:scheme,host,port,path,query,fragment

test://shangjia:8888/shangjiaDetail?shangjiaId=222#watson
scheme : test
host : shangjia
port : 8888
path : /shangjiaDetail
query : shangjiaId=222
fragment : watson

注:
1.除了scheme、host是必须要有的,其它的几个port 、path、query、fragment,它们每一个可以选择性的要或不要,但顺序不能变。
2.其中[host:port]部分我们也可以称为authority。
3.在scheme和fragment之间的部分我们也可以称为scheme-specific-part。

[scheme:]scheme-specific-part[#fragment]
[scheme:][//authority][path][?query][#fragment]
[scheme:][//host:port][path][?query][#fragment]  

代码提取

上面我们通过实例讲解了肉眼识别Uri更部分的方式,但在代码中又要怎样提取呢。下面就看看Uri中提取各部分的接口,我们换一个Uri字符串:

http://www.java.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4#watson

getScheme() :获取Uri中的scheme字符串部分,在这里即http
getSchemeSpecificPart():获取Uri中的scheme-specific-part:部分,这里是://www.java.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4
getFragment():获取Uri中的Fragment部分,即watson
getAuthority():获取Uri中Authority部分,即www.java.com:8080
getPath():获取Uri中path部分,即/yourpath/fileName.htm
getQuery():获取Uri中的query部分,即stove=10&path=32&id=4
getHost():获取Authority中的Host字符串,即www.java.com
getPost():获取Authority中的Port字符串,即8080

另外还有两个常用的:getPathSegments()、getQueryParameter(String key)
List< String> getPathSegments():上面我们的getPath()是把path部分整个获取下来:/yourpath/fileName.htm,getPathSegments()的作用就是依次提取出Path的各个部分的字符串,以字符串数组的形式输出。
getQueryParameter(String key):在上面我们通过getQuery()获取整个query字段:stove=10&path=32&id=4,getQueryParameter(String key)作用就是通过传进去path中某个Key的字符串,返回他对应的值。

scheme 使用

AndroidMainfest.xml 配置 scheme

<application
        android:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><!--服务器下发跳转路径跳转Activity--><activity
            android:name=".GoodsDetailActivity"android:theme="@style/AppTheme"><intent-filter><!--协议部分,随便设置--><data android:scheme="watson" android:host="goods" android:path="/goodsDetail" android:port="8888"/><!--下面这两项必须得设置--><category android:name="android.intent.category.DEFAULT"/><action android:name="android.intent.action.VIEW"/></intent-filter></activity><!--H5页面点击描点跳转Activity--><activity android:name=".LoginActivity"><intent-filter><!--下面这两项必须得设置--><action android:name="android.intent.action.VIEW" /><category android:name="android.intent.category.DEFAULT" /><!--如果通过网页中点击链接跳转下面这项也必须得设置--><category android:name="android.intent.category.BROWSABLE" /><data
                    android:host="login"android:scheme="test" /><data
                    android:host="start"android:scheme="test" /> </intent-filter></activity></application>

这样我们便定义了能够接受scheme请求的activity实例,当网页或者是Android代码发送这种规则scheme的请求的时候就能够调用起对应的Activity了。

通过服务器下发跳转路径跳转相应页面

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("watson://goods:8888/goodsDetail?goodsId=10011002"));
startActivity(intent);

这里的”watson://goods:8888/goodsDetail?goodsId=10011002”就是服务器下发的跳转路径,当我们执行startActivity的时候就会调起GoodsDetailActivity,然后我们可以在GoodsDetailActivity种解析出scheme的内容,再做相应处理。

public class GoodsDetailActivity extends Activity{public String TAG = "huaxun";public void onCreate(Bundle b) {super.onCreate(b);setContentView(R.layout.activity_detail);Uri uri = getIntent().getData();if (uri != null) {// 完整的url信息String url = uri.toString();Log.e(TAG, "url: " + uri);// scheme部分String scheme = uri.getScheme();Log.e(TAG, "scheme: " + scheme);// host部分String host = uri.getHost();Log.e(TAG, "host: " + host);//port部分int port = uri.getPort();Log.e(TAG, "port: " + port);// 访问路径String path = uri.getPath();Log.e(TAG, "path: " + path);// Query部分String query = uri.getQuery();Log.e(TAG, "query: " + query);//获取指定参数值String goodsId = uri.getQueryParameter("goodsId");Log.e(TAG, "goodsId: " + goodsId);}}
}

看Log信息:

通过H5页面的锚点跳转相应的页面

首先需要一个HTML文件:

<!DOCTYPE html>
<html>
<head><title>Js调用Android</title>
</head><body>
<a href="test://start/?id=431&name=watson&age=29">跳转start</a>
<a href="test://web/?id=432&name=jack&age=28">跳转web</a>
<a href="test://login/?id=433&name=tom&age=27">跳转Login</a>
</body>
</html>

Java中需要加载这个本地页面,并设置WebViewClient。

        web.loadUrl("file:///android_asset/web.html");web.setWebViewClient(new WebViewClient() {@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {Log.v("huaxun","view = [" + view + "], url = [" + url + "]");Uri uri = Uri.parse(url);String id = uri.getQueryParameter("id");String name = uri.getQueryParameter("name");String age = uri.getQueryParameter("age");Log.v("huaxun","id:" + id);Log.v("huaxun","name:" + name);Log.v("huaxun","age:" + age);if (url.startsWith("test://login")) {Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("test://login/userDetail?id="+id+"&name="+name+"&age="+age));startActivity(intent);}return true;}

可以发现我们为Webview设置了WebViewClient,并重写了WebViewClient的shouldOverrideUrlLoading方法,然后我们解析锚点的url,并根据解析的内容调起LoginActivity。

如果我们不想设置WebViewClient,当点击H5页面的锚点url也是可以直接跳转Activity的,是怎么实现的呢?
(1)Intent-filter中的各种匹配工作,还应该加上一个属性:

<category android:name="android.intent.category.BROWSABLE"/>

(2)点击的url需要和Mainfest中LoginActivity配置的Scheme等数据相对应。

只要实现了以上两点就可以点击url轻松实现跳转。但是还是不建议这么做,因为在项目中可能URL Scheme协议并不止一个界面。如果你在AndroidMainfest.xml里面去给每一个可能相关的界面都配置scheme属性,那你整个界面看着也不美观,而且还都是重复的配置。所以还是建议根据URL地址来判断跳转。

根据服务器下发通知跳转相应的界面

同样的逻辑。把服务器下发的通知栏消息,里面的URL地址数据拿到,进行解析判断,然后跳转到相应的界面。

NotificationManager notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);NotificationCompat.Builder builder;builder = new NotificationCompat.Builder(MainActivity.this);builder.setSmallIcon(R.mipmap.ic_launcher).setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)).setContentTitle("watson").setContentText("test schemeURL").setTicker("有新消息").setOngoing(false).setWhen(System.currentTimeMillis()).setPriority(Notification.PRIORITY_DEFAULT).setAutoCancel(true);Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("watson://goods:8888/goodsDetail?goodsId=10011002"));PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);builder.setContentIntent(pendingIntent);Notification notification = builder.build();notifyManager.notify(1, notification);

有关Notification的知识,我就不再讲了,最重要的是PendingIntent的封装!

DEMO下载地址

Android应用内跳转Scheme协议相关推荐

  1. android h5页面跳转,android H5 应用内跳转Scheme协议

    什么是URL Scheme 概述: android中的scheme是一种页面内跳转协议,是一种非常好的实现机制,通过定义自己的scheme协议,可以非常方便跳转app中的各个页面:通过scheme协议 ...

  2. Android应用内跳转到google play或者其他应用市场详情页下载或者评价

    1. google play应用商店 小米手机上对该代码进行了验证,安装有google play和小米应用商店,直接启动的是小米应用商店. 验证环境 红米note3 Android 6.0系统 // ...

  3. android页面跳转时获取地址栏,Android 利用scheme页面内跳转协议进行跳转

    什么是 URL Scheme? android中的scheme是一种页面内跳转协议. 通过定义自己的scheme协议,可以非常方便跳转app中的各个页面: 通过scheme协议,服务器可以定制化告诉A ...

  4. Android 中Scheme协议的使用详解唤起Activity或App

    1. 什么是URL Scheme? 是一种页面内跳转协议:通过定义自己的scheme协议,可以非常方便跳转app中的各个页面. 2.什么时候使用 服务器下发跳转路径,客户端根据服务器下发跳转路径跳转相 ...

  5. Android 中 Scheme 协议的使用详解

    什么是 URL Scheme? 简单的说就是 android 中的一种页面内跳转协议,方便 app 页面的内的跳转 2.什么时候使用 服务器下发跳转路径,客户端根据 服务器下发跳转路径跳转相应的页面 ...

  6. Android 中Scheme协议的使用详解

    1. 什么是URL Scheme? 简单的说就是android中的一种页面内跳转协议,方便app页面的内的跳转 2.什么时候使用 服务器下发跳转路径,客户端根据 服务器下发跳转路径跳转相应的页面 H5 ...

  7. Android通过Scheme协议打开APP界面

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/123238777 本文出自[赵彦军的博客] 文章目录 浏览器为什么能唤起App的页面 ...

  8. android 通过类名跳转activity,Activity跳转方式总结

    一.显式调用方法 方法一: Intent intent=new Intent(本类,将要跳转的类); //Intent intent=new Intent(MainActivity.this,Jump ...

  9. 运用scheme协议唤起外部app

    最近所做的项目中有一个需要唤醒外部APP的功能,甲方要求在接入是需要用scheme方式.为此,本人查了一些资料,在研究的基础上进行了开发.现总结如下: 什么是scheme的唤起方式 首先,需要指出的是 ...

  10. android activity的跳转,Android Activity跳转方式总结分享

    自我感觉这里的排版看着更舒服些. Activity跳转方式总结 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...

最新文章

  1. go语言任意代码执行漏洞 cve-2018-6574
  2. jsp页面截取字符串,显示指定长度
  3. sql java blob_JAVA和SQL关于BLOB的很大的问题?……
  4. 【编译原理】CFG分析树
  5. oppoJava面试题,java声明全局变量的关键字
  6. 2021中国到店消费新趋势洞察报告
  7. Makefile简易教程
  8. 【英语学习】【Level 07】U05 Best Destination L4 A perfect destination
  9. JDK5新特性之一----静态导入
  10. 华为路由与交换 eSight 基本功能学习笔记
  11. AR Engine光照估计能力,让虚拟物体在现实世界更具真实感
  12. SQL零基础入门学习(三)
  13. 周志华机器学习笔记(一)
  14. 缠中说禅108课》87:逗庄家玩的一些杂史 4
  15. Broadcast Receiver @
  16. erp5开源制造业erp电子商务模块介绍
  17. 嵌入式开发:使用STM32CubeMX 和 Keil uVision5实现两位数码管循环显示实验
  18. jQuery-WEUI(jqweui)的Uploader图片上传方法2.0
  19. 基于Node+Vue+Express开发实现商城系统
  20. python实现按键精灵的功能_利用Python实现Windows下的鼠标键盘模拟的实例代码

热门文章

  1. 某虚拟存储系统采用最近最少使用(LRU)页面淘汰算法,假定系统为每个作业分配4个页面的主存空间--软考系统架构设计师--不会做题?“猿”来绘个图解决吧
  2. 飞鸽TCP/IP 10106错误解决
  3. 儿童节html5小游戏,2016六一儿童节主题班会小游戏大全
  4. 算法导论--麻省理工学院公开课
  5. DISC社交风格测试题--老虎 孔雀 考拉 猫头鹰
  6. [EXtJS5学习笔记]第一节 Sencha Cmd 学习笔记 简介 Sencha Cmd是什么
  7. Java中反射机制入门
  8. 轮子王-原创数据结构-V2.0--内存//二级指针//小样儿练习
  9. 难解次级债内乱 美国众议院反咬中国金融开放
  10. ImportError:cannot import name ‘save_state_warning‘和解决torch1.7.1报分布式错误No rendezvous handler for env: