#黑科技# 跳出浏览器
当移动浪潮来袭,不管是传统 PC 网站/应用,仍是新兴的移动互联网,都一并蜂拥的走进用户的手机。提供一个便于手机浏览的 Web 页面,再造一个功能丰富的移动 App 成了每一个产品的标配。提供移动 Web 页面,可使得用户更易获取产品信息,在微信上、微博中,搜索里点个连接,就能够马上享用产品功能;而提供移动 App,则能够提供更好的产品体验,使用 native api 能构建更丰富的特点功能,提供更出众的性能表现。html
来想象一下这个场景,当别人发给你一个连接,是知乎问题「豌豆荚的员工工做方式是什么样的?」,你在手机浏览器上慢吞吞的加载好了,答案看得特别激动想点个赞。结果发现,还!要!登!录!我明明已经安装了知乎的 App 好吗!为啥不让我愉快的在知乎 App 上操做呐?java
这就是本 #黑科技# 的主题,有了移动 Web 页面,又提供了移动 App,如何能让二者更完美的结合在一块儿呢?当用户已经安装了 App 的前提下,访问移动端 Web 页面时,能够无缝的跳转到 App 中对应的位置去?
依然举上面那个栗子,知乎的同窗其实已经有了解决方案,就是「打开应用」那个按钮,若是已经安装了知乎 App,点击后就会从浏览器跳转到应用中了。相似于这样的按钮,背后的技术方案是什么?有哪些局限性?有没有什么一招搞定的必杀技?这就是本文讨论的主要内容。android
第一招:拦截 Http 跳转
在 Android 中,最标准的方式,就是在应用的配置文件 AndroidManifest.xml 中,经过 <activity> 标签里的 <intent-filter> 来声明:“本应用能够更好的处理某些 url 对应的页面,浏览器你交给我吧”。套在例子上,声明形如:git
<activity android:name=”com.zhihu.android.QuestionActivity”>
<intent-filter>
<action android:name=”android.intent.action.VIEW” />
<category android:name=”android.intent.category.DEFAULT” />
<category android:name=”android.intent.category.BROWSABLE” />
<!-- 关键所在,匹配相应域名和 url 模式 -->
<data android:scheme=”http” android:host=”www.zhihu.com”
android:pathPattern=”/question/.*” />
</intent-filter>
</activity>
作了上述的声明以后,在 Chrome 里访问 豌豆荚的员工工做方式是什么样的?,即可以跳转到知乎 Android 客户端,并打开这个问题的页面。不过这个解决方案有挺多问题,最重要的一个缘由是:“兼容性”。web
除了 Chrome,从豌豆荚上的下载量看,最热门的手机浏览器是这些:ajax
而以上浏览器,大都不遵照 Android 的协定,不支持经过匹配 url 跳转到更适合的应用中去。臆测其缘由,大抵是国内浏览器都不肯将流量导给其余应用吧。chrome
第二招:自定义 Scheme
如此,那就另辟蹊径,既然 http 协议的 url 会被不少浏览器拦自行处理掉,那就不用 http 协议而采用自定义的 scheme 试试看。api
将 AndroidManifest.xml 中的声明修改以下:浏览器
<activity android:name=”com.zhihu.android.QuestionActivity”>
<intent-filter>
<action android:name=”android.intent.action.VIEW” />
<category android:name=”android.intent.category.DEFAULT” />
<category android:name=”android.intent.category.BROWSABLE” />
<!-- 关键所在,匹配相应的 scheme -->
<data android:scheme=”zhihu” android:host=”questions” />
</intent-filter>
</activity>
把「打开应用」的跳转连接设置为形如 ”zhihu://questions/…“ 的 url,点击后就能够匹配跳转到应用对应的 activity 中去。固然,若是简单的使用 <a> 标签来作这件事情,若手机中未安装知乎客户端,点击后就会跳转到一个错误页面(地址是 zhihu://questions/…)。解决方案也简单,使用 <iframe> 便可,详情就不在此赘述。安全
第三招:Chrome Intent
自定义的 scheme 能够搞定不少浏览器,但 Chrome 除外。缘由是为了更有序的打通浏览器页面和本地应用,Chrome 25 后再也不支持自定义的 scheme,而推出了 Chrome Intent,做为标准协议进行推广,其格式形如:
intent:
//scan/
#Intent;
package=com.google.zxing.client.android;
scheme=zxing;
end;
Chrome Intent 首先将 scheme 统一为 ”intent“,大量信息放到了锚点 ”#“ 以后,称做 ”fragment“(此 fragment 非彼 fragment),它描述了由谁来接收这个 uri。fragment 中能够指定打开这个 uri 的包名,或者是 action、extra,等等。使用 Intent.parseUri 函数能够将这样的 uri 直接转成一个 intent 对象,反之调用 Intent.toUri 函数可将 intent 对象序列化如此格式的 uri。
应用到知乎这个例子里,在 AndroidManifest.xml 中的声明与自定义 scheme 写法彻底一致,只是在调用时,须要在跳转连接中写成以下格式:
intent:
//questions/...
#Intent;
package=com.zhihu.android;
scheme=zhihu;
end;
呼微博客户端:
<a id="test" href="intent:#Intent;package=com.sina.weibo;scheme=sinaweibo://splash/;end">test</a>
第四招:open方式
呼微博客户端:
var o = "sinaweibo://splash/";
var j = window.open(o, "_blank");
setTimeout(function() {
j.close();
}, 0);
ome Intent 首先将 scheme 统一为 ”intent“,大量信息放到了锚点 ”#“ 以后,称做 ”fragment“(此 fragment 非彼 fragment),它描述了由谁来接收这个 uri。fragment 中能够指定打开这个 uri 的包名,或者是 action、extra,等等。使用 Intent.parseUri 函数能够将这样的 uri 直接转成一个 int
必杀技:内嵌 Http 服务
至此,只要利用 UA 信息,合理使用自定义 scheme 和 Chrome Intent,就能够搞定市面上几乎所有的浏览器,这就完了吗?固然没有!
随着以微信为表明的社交应用的不断发展,它内嵌的 WebView 已然成为一个轻型浏览器了,坐拥巨大的用户和内容分享量,微信等应用带来的页面访问量是不容忽视的。但这些应用的 WebView 一般是禁止外链的,不管是什么 scheme 在这里一概很差使,这就使得分享到微信的知乎问题,就是再点击「打开应用」都是无效的。
有办法解决么?固然,是有的,”黑科技“ 粉墨登场的时刻到了。你们都知道,web 页面能够发起 ajax 请求用来与服务器交互,若是这个 ”服务器“ 不在云端,而是在本机呢?没错,解决方案就是在应用中绑定本地端口,启动一个 http 服务,来响应发送过来的请求,打开应用或者是作其余事情。
若是,知乎应用在后台启动 http 服务,绑定一个端口,好比:12306 吧。那 web 页面能够发送以下的 ajax 请求来实现打开应用:
$.ajax({
url: "http://127.0.0.1:12306/open?intent=...",
}).done(function() {
// do what you want
});
固然,要作的足够细致,还须要实现相似于 ”http://127.0.0.1:12306/is_installed“ 这样的 api,若是知乎安装了,返回 200,若是服务未启动或者知乎未安装,天然是会返回 404,由此能够在 web 页面中判断是否安装了知乎应用,进而决定是否要显示「打开应用」的按钮。
一般,必杀技都是有反作用的,若是须要准确的判断是否安装了知乎,就须要这个 http 服务始终存活,不然就没启动和没安装傻傻分不清楚了。至于如何使得 “一个已安装应用在各类状况下都保持后台运行”,则是另外一个充满了黑科技的领域,待往后再聊聊这个话题。
PS:启动后台 http 服务的代码,在豌豆荚 git 中保持 review 不经过的状态估计都得有一年了,由于豌豆荚 Android 应用 “用户不主动开启相关功能则不容许后台常驻” 的原则相悖。因此若是有天你在微信页面中忽然打开了某个 “安全” 应用、“搜索” 应用,千万别以为神奇,而是在看看本文,琢磨一下那是付出什么换来的。
本文做者:
张楠 ,豌豆荚工程师。目前专一于各类黑科技及 Growth Hacking 手段。欢迎 E-mail 与 (tou) 我 (jian) 交 (li) 流 (ba):zhangnan@wandoujia.com。
原文:http://zhuanlan.zhihu.com/andlib/19848910#!