不少人會遇到這個問題,大多數都是站在移動端的角度去解釋這個問題,本篇文章將會從web端的角度分析問題,解決問題html
用戶和流量的量級決定了一款互聯網產品的優秀度。對一款優雅的互聯網產品而言,app端和web端是必不可少的,咱們藉助它們造成閉環,保證用戶體驗和活躍度。除了端的覆蓋,咱們還要作到端到端的交互,由此咱們提出了產品的需求: wap頁喚起app,若是用戶沒裝app則跳轉到下載頁(引導頁都行)。若是用戶已安裝,根據URL跳到app內指定的界面,這也正是本文正要解決的問題android
舉個🌰:web
wzry://videolists.show/mark/penta_kill?num=1
複製代碼
這種方式須要事先在app中註冊相應的scheme,經過網頁訪問已註冊的scheme,達到調起App客戶端及相關界面json
<activity android:name=".ui.SchameFilterActivity">
<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="videolists.show"
android:path="/mark/penta_kill"
android:scheme="wzry"/>
</intent-filter>
</activity>
複製代碼
好了咱們能夠愉快的使用了瀏覽器
<a href="wzry://videolists.show//mark/penta_kill?vid=666">你過來啊!</a>
複製代碼
(你也用直接訪問地址的方式,這種方式有小坑:有些瀏覽器是會返回404狀態碼,或者變成搜索結果頁,小煩)bash
聲明sheme後,回過頭來看一下需求:用戶安裝了app,調起app。用戶未安裝咱們須要引導用戶下載 。那這裏就有一個問題了:網頁是不知道用戶有沒有安裝app的。那咱們換一個思路----可不能夠知道頁面被置於後臺了?頁面進入後臺,能夠認爲是喚起成功了;頁面沒進入後臺,說明喚起失敗(沒安裝or其餘緣由)微信
一個新的API徹底知足上邊提到的需求 : Page Visibility API,文檔中詳細的介紹了這個API---->能夠準確的知道頁面當前的狀態(前臺,後臺等狀態),可是這個API太新了,須要較新的瀏覽器支持,覆蓋率有點低。放一張圖感覺一下:app
我先說一下思路:ide
setTimeout的實現過程:ui
瀏覽器嘗試打開URL scheme並記錄時間點t1,在2秒計時後,檢查當前時間t2,若是t2-t1 > 2200ms,說明喚起app成功(喚起app會是瀏覽器的定時器延後執行),若是t2-t1 < 2200ms,可能沒有安裝app,能夠引導用戶進入下載頁
setInterval實現過程
原理上跟setTimeout類似,方法上換成設置一個比較小的時間間隔(例如20ms),運行屢次(例如100),比較運行完100次的總耗時與20*100的時間差。邏輯判斷同setTimeout
優缺點:
setTimeout不穩定,由於Android是基於Linux分時多任務的,setTimeout的基準誤差不會那麼大,比較難調教
setInterval要好一點,頁面一直處於前臺(調起app失敗),則100次跑完,總耗時與 100x20=2000ms不會有太大差別,但頁面在後臺運行時(調起app成功),此時間會明顯超過2000ms
好了嘴炮打完,上🌰:
setTimeout
var openTime = +new Date();
window.location.href = 'wzry://videolists.show/mark/penta_kill?num=1'
var timer = setTimeout(function () {
if ((new Date()) - openTime < 2200) {//加了200ms基準偏差
window.location.href = 'you app download page';
}
if ((new Date()) - openTime > 2200) {
clearTimeout(timer);
}
}, 2000);
複製代碼
setInterval
var limit_num = 100;
var openTime = +new Date();
window.location.href = 'wzry://videolists.show/mark/penta_kill?num=1'
var timer = setInterval(function () {
if(limit_num > 0){
limit_num--;
}else{
if ((new Date()) - openTime < 2200) {//加了200ms基準偏差
window.location.href = 'you app download page';
}
clearTimeout(timer);
}
}, 20);
複製代碼
當咱們完成這些操做以後,在通常環境下是能夠正常喚起app的了
像這種爸爸級別的應用是有scheme白名單的,只有白名單內的scheme纔不會被過濾掉,就問你怕不怕?嗯?
像這種咱們怎麼去解決那?
使用它頒發給你的應用地址,向這個地址跳轉,而後一切就交給爸爸了,直接無視微信什麼的,直接帶你飛到app內
它是iOS9推出的一項強大的功能。可讓你 經過http連接的方式喚起你的app(無論你的在微信/微博仍是其餘app內,由於Universal Links是由系統直接處理的),下面我來簡單說一下怎麼使用Universal Links完成喚醒的app,你也能夠經過官方文檔詳細的瞭解它。
首先
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TeamID + BundleId TeamID",
"paths": [ "/mark/penta_kill?num="]
}
]
}
}
複製代碼
作完這些,你就能夠嘗試喚起你的iOS app了
這裏還要強調一下 攔截的地址 必定要與當前webview的url 不在同一個域名下。這樣Universal Links纔會生效,不要問我怎麼知道的,都是血淚啊
綜上,Android app除了使用應用寶跳轉喚起和引導頁沒發現其餘更好的辦法,iOS方案多了個Universal Links,這也是爲何咱們常常看到有些app在微信/微博中 iOS端能夠直接喚起app,而Android端常常是須要走一道應用寶的緣由
好了,以上內容就是我對喚起app的一些總結和經驗,但願能夠幫助到你
修改 : 通過驗證微信添加了一個屏蔽Universal Links的爆炸功能,大體原理參考:Prevent universal links from opening in WKWebView
/UIWebView
微信內置瀏覽器想怎麼改就怎麼改,厲害厲害