【Android開發(fā)高級系列】應用間跳轉(zhuǎn)專題

1 Intent簡介

? ??????Android中提供了Intent機制來協(xié)助應用間的交互與通訊,Intent負責對應用中一次操作的動作、動作涉及數(shù)據(jù)、附加數(shù)據(jù)進行描述,Android則根據(jù)此Intent的描述,負責找到對應的組件,將 Intent傳遞給調(diào)用的組件,并完成組件的調(diào)用。Intent不僅可用于應用程序之間,也可用于應用程序內(nèi)部的Activity/Service之間的交互。因此,Intent在這里起著一個媒體中介的作用,專門提供組件互相調(diào)用的相關信息,實現(xiàn)調(diào)用者與被調(diào)用者之間的解耦。在SDK中給出了Intent作用的表現(xiàn)形式為:

? ? 1、通過Context.startActivity()? ? orActivity.startActivityForResult() 啟動一個Activity;

? ? 2、通過 Context.startService() 啟動一個服務,或者通過Context.bindService() 和后臺服務交互;

? ? 3、通過廣播方法(比如 Context.sendBroadcast(),Context.sendOrderedBroadcast(),? Context.sendStickyBroadcast()),發(fā)給broadcast receivers。

? ??????Intent可分為隱式(implicitly)和顯式(explicitly)兩種:

1.1 顯式Intent

? ? ? ?即在構造Intent對象時就指定接收者,它一般用在知道目標組件名稱的前提下,一般是在相同的應用程序內(nèi)部實現(xiàn)的,如下:

Intent intent = new Intent(MainActivit.this, NewActivity.class);?

startActivity(intent );

????????上面那個intent中,直接指明了接收者:NewActivity

1.2 隱式Intent

????????即Intent的發(fā)送者在構造Intent對象時,并不知道也不關心接收者是誰,有利于降低發(fā)送者和接收者之間的耦合,它一般用在沒有明確指出目標組件名稱的前提下,一般是用于在不同應用程序之間,如下:

Intent intent = new Intent();

intent.setAction("com.wooyun.test");

startActivity(intent);

????????上面那個intent,沒有指明接收者,只是給了一個action作為接收者的過濾條件。

??? ????對于顯式Intent,Android不需要去做解析,因為目標組件已經(jīng)很明確,Android需要解析的是那些隱式Intent,通過解析,將Intent映射給可以處理此Intent的Activity、IntentReceiver或Service。

1.3 Intent Filter匹配規(guī)則

????????Intent解析機制主要是通過查找已注冊在AndroidManifest.xml中的所有IntentFilter及其中定義的Intent,最終找到匹配的Intent。在這個解析過程中,Android是通過Intent的action、type、category這三個屬性來進行匹配判斷的。一個過濾列表中的action、type、category可以有多個,所有的action、type、category分別構成不同類別,同一類別信息共同約束當前類別的匹配過程。只有一個Intent同時匹配action、type、category這三個類別才算完全匹配,只有完全匹配才能啟動Activity。另外一個組件若聲明了多個Intent Filter,只需要匹配任意一個即可啟動該組件。?例如:

1.3.1 (1)action的匹配規(guī)則

? ? ? ?action是一個字符串,如果Intent指明定了action,則目標組件的IntentFilter的action列表中就必須包含有這個action,否則不能匹配。一個Intent Filter中可聲明多個action,Intent中的action與其中的任一個action在字符串形式上完全相同(注意,區(qū)分大小寫,大小寫不同但字符串內(nèi)容相同也會造成匹配失?。?,action方面就匹配成功??赏ㄟ^setAction方法為Intent設置action,也可在構造Intent時傳入action。需要注意的是,隱式Intent必須指定action。比如我們在Manifest文件中為MyActivity定義了如下Intent Filter:

????????那么只要Intent的action為“SEND”或“SEND_TO”,那么這個Intent在action方面就能和上面那個Activity匹配成功。比如我們的Intent定義如下:

Intent intent = new Intent("android.intent.action.SEND") ;

startActivity(intent);

????????那么我們的Intent在action方面就與MyActivity匹配了。

????????Android系統(tǒng)預定義了許多action,這些action代表了一些常見的操作。常見action如下(Intent類中的常量):

????Intent.ACTION_VIEW

????Intent.ACTION_DIAL

????Intent.ACTION_SENDTO

????Intent.ACTION_SEND

????Intent.ACTION_WEB_SEARCH

1.3.2 (2)data的匹配規(guī)則

????????如果Intent沒有提供type,系統(tǒng)將從data中得到數(shù)據(jù)類型。和action一樣,同action類似,只要Intent的data只要與Intent Filter中的任一個data聲明完全相同,data方面就完全匹配成功。?

? ??????data由兩部分組成:mimeType和URI?;

? ??????MineType指的是媒體類型:例如imgage/jpeg,auto/mpeg4和viedo/*等,可以表示圖片、文本、視頻等不同的媒體格式?;

????????uri則由scheme、host、port、path | pathPattern | pathPrefix這4部分組成

????<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]

????????例如:?

content://com.wooyun.org:200/folder/etc?

http://www.wooyun.org:80/search/info

? ? ? ?Intent的uri可通過setData方法設置,mimetype可通過setType方法設置。?需要注意的是:若Intent Filter的data聲明部分未指定uri,則缺省uri為content或file,Intent中的uri的scheme部分需為content或file才能匹配;若要為Intent指定完整的data,必須用setDataAndType方法,究其原因在,setData和setType方法的源碼中我們發(fā)現(xiàn):

? ??pathpathPrefix、pathPattern?之間的區(qū)別  

? ??????這里主要說的區(qū)別是?path、pathPrefix、pathPattern?之間的區(qū)別:

????· path?用來匹配完整的路徑,如:http://example.com/blog/abc.html,這里將 path 設置為 /blog/abc.html 才能夠進行匹配;

????· pathPrefix?用來匹配路徑的開頭部分,拿上來的 Uri 來說,這里將 pathPrefix 設置為 /blog 就能進行匹配了;

????· pathPattern?用表達式來匹配整個路徑,這里需要說下匹配符號與轉(zhuǎn)義。

????匹配符號:

????1. “*” 用來匹配0次或更多,如:“a*” 可以匹配“a”、“aa”、“aaa”...

????2. “.” 用來匹配任意字符,如:“.” 可以匹配“a”、“b”,“c”...

????3. 因此 “.*” 就是用來匹配任意字符0次或更多,如:“.*html” 可以匹配“abchtml” 、 “chtml”、 “html”、“sdf.html”...

????????轉(zhuǎn)義:因為當讀取 Xml 的時候,“/” 是被當作轉(zhuǎn)義字符的(當它被用作 pathPattern 轉(zhuǎn)義之前),因此這里需要兩次轉(zhuǎn)義,讀取 Xml 是一次,在 pathPattern 中使用又是一次。如:“*” 這個字符就應該寫成 “//*”,“/” 這個字符就應該寫成 “////”。

2 IntentFilter跳轉(zhuǎn)方案

2.1 方案設計

2.1.1 跳轉(zhuǎn)App方案

????????流程方案是在Android工程的AndroidManifest.xml中,將LauncherActivity作為拉起App后的頁面,在微信文章頁面,分兩種情況處理:

????1、對于能支持直接跳轉(zhuǎn)的,例如華為、小米等大部分手機,引導用戶通過右上角點擊“在瀏覽器中打開”按鈕,然后頁面會彈出目標App的選項框;

????2、對于不能支持直接跳轉(zhuǎn)的,例如三星S7,則跳轉(zhuǎn)到應用寶頁面,利用微信的跳轉(zhuǎn)來打開;

2.1.2 App中子頁面跳轉(zhuǎn)方案設計

????????依托原有的linkType與localPath外網(wǎng)跳轉(zhuǎn)方案,在微信位置的跳轉(zhuǎn)鏈接中加上linkType與localPath兩個參數(shù),用來拉起App的具體二級頁面。而拉起頁面后,導航條數(shù)據(jù)則通過localPath直接從js端獲取就行。

2.2 核心代碼

核心代碼示例如下:

我們App中Url Scheme設計如下:


2.3 落地方案

2.3.1 域名規(guī)劃

????????Android中是通過域名+一級路徑來支持url跳轉(zhuǎn)App,目前預研時支持官網(wǎng)指定路徑與微信的指定目錄的所有路徑的跳轉(zhuǎn)。

2.3.2 跳轉(zhuǎn)后頁面呈現(xiàn)方案設計

????????在HJDev的架構中,App中打開的頁面分為了外網(wǎng)、微信文章、活動、本地web頁面、原生頁面這幾類,通過linkType來標記。故在微信App中調(diào)起App后,可通過url參數(shù)將linkType、目標頁面url傳遞過來。而HJDev App依據(jù)此內(nèi)容直接創(chuàng)建對應頁面的實例入棧顯示。

????????其中要注意的細節(jié)點是,頁面原生導航欄的描述數(shù)據(jù)可以使用url從h5端動態(tài)獲取。

String *jsonStr = "hj.NativeViewUtil.NavDataFactory.getNavDataByPathForJson(" + localRePath + '')";

????????故在微信跳轉(zhuǎn)地址中,需要傳遞如下參數(shù):

??????????? linkType, localpath,如果目標頁面需要傳遞參數(shù),則localpath中必須帶上。

????LinkType取值規(guī)則如下:

??????????? 0:普通web頁面;

??????????? 1:活動頁面;

??????????? 2:微信文章頁面;

??????????? 3:本地web頁面;

??????????? 4:原生頁面;


2.3.3 原生端跳轉(zhuǎn)規(guī)則設計:

????1、只對hjdev.com域名url進行攔截處理;

????2、如果url中不包含localpath參數(shù),則分兩種情況:

????????a) 如果是wx相關域名,則直接取url做路由入棧跳轉(zhuǎn);

????????b) 其他的(包括不含參數(shù)情況),則直接跳轉(zhuǎn)首頁;

????3、如果包含localpath參數(shù),則分兩種情況:

????????a) 如果localpath參數(shù)為-1,則取當前url做路由入棧跳轉(zhuǎn);

????????b) 如果localpath參數(shù)為-2,則直接拉起App;

????????c) 如果參數(shù)值是一個url,則進行urlDecode處理后,做路由入棧跳轉(zhuǎn);

????????d) 否則直接拉起App;

????4、做路由入棧跳轉(zhuǎn)時,應將linktype參數(shù)也攜帶進去,同時根據(jù)url從h5獲取頭部數(shù)據(jù)結構也攜帶進去;

3 參考鏈接

iOS/Android瀏覽器(h5)及微信中喚起本地APP

http://www.cnblogs.com/shadajin/p/5724117.html


(Good)android/iPhone:如何從browser直接打開應用程序或者打開應用商店(如果沒有應用程序)

http://blog.csdn.net/hundsong/article/details/6623500


Android平臺好友點擊微信分享的內(nèi)容后跳轉(zhuǎn)來源App的實現(xiàn)方案研究

http://www.2cto.com/kf/201409/330877.html


Android開發(fā)--Intent-filter屬性詳解

http://blog.csdn.net/wuwenxiang91322/article/details/7671593#


?你必須弄懂的IntentFilter匹配規(guī)則

http://blog.csdn.net/mynameishuangshuai/article/details/51673273


Intent和IntentFilter詳解

http://blog.csdn.net/cnnumen/article/details/8464786


(Good)iOS/Android瀏覽器(h5)及微信中喚起本地APP

http://www.cnblogs.com/shadajin/p/5724117.html


Android開發(fā)之Intent.Action

http://www.cnblogs.com/hanyonglu/archive/2012/03/26/2417278.html


(Good)在手機的瀏覽器上通過連接打開App

http://www.cnblogs.com/sexintercourse/p/5898242.html


更新:通過瀏覽器直接打開Android應用程序

https://my.oschina.net/liucundong/blog/354029


(Good)Android實現(xiàn)通過瀏覽器點擊鏈接打開本地應用(APP)并拿到瀏覽器傳遞的數(shù)據(jù)

http://blog.csdn.net/jiangwei0910410003/article/details/23940445

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容