#黑科技# 跳出瀏覽器
當移動浪潮來襲,不管是傳統 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#!