精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

瀏覽器為什么能喚起App的Activity?

系統(tǒng) 瀏覽器
我們沒有主動聲明Activity的class,那么系統(tǒng)是怎么為我們找到對應(yīng)的Activity的呢?其實這里和正常的Activity啟動流程是一樣的,無非是if / else的實現(xiàn)不同而已。

[[425568]]

本文轉(zhuǎn)載自微信公眾號「咸魚正翻身」,作者MDove。轉(zhuǎn)載本文請聯(lián)系咸魚正翻身公眾號。

疑問的開端

大家有沒有想過一個問題:在瀏覽器里打開某個網(wǎng)頁,網(wǎng)頁上有一個按鈕點擊可以喚起App。

這樣的效果是怎么實現(xiàn)的呢?瀏覽器是一個app;為什么一個app可以調(diào)起其他app的頁面?

說到跨app的頁面調(diào)用,大家是不是能夠想到一個機制:Activity的隱式調(diào)用?

隱式啟動原理

當我們有需要調(diào)起其他app的頁面時,使用的API就是隱式調(diào)用。

比如我們有一個app聲明了這樣的Activity:

  1. <activity android:name=".OtherActivity" 
  2.     android:screenOrientation="portrait"
  3.     <intent-filter> 
  4.         <action android:name="mdove"/> 
  5.         <category android:name="android.intent.category.DEFAULT"/> 
  6.     </intent-filter> 
  7. </activity> 

其他App想啟動上邊這個Activity如下的調(diào)用就好:

  1. val intent = Intent() 
  2. intent.action = "mdove" 
  3. startActivity(intent) 

我們沒有主動聲明Activity的class,那么系統(tǒng)是怎么為我們找到對應(yīng)的Activity的呢?其實這里和正常的Activity啟動流程是一樣的,無非是if / else的實現(xiàn)不同而已。

接下來咱們就回顧一下Activity的啟動流程,為了避免陷入細節(jié),這里只展開和大家相對“耳熟能詳”的類和調(diào)用棧,以串流程為主。

跨進程

首先我們必須明確一點:無論是隱式啟動還是顯示啟動;無論是啟動App內(nèi)Activity還是啟動App外的Activity都是跨進程的。比如我們上述的例子,一個App想要啟動另一個App的頁面,至少涉及3個進程。

注意沒有root的手機,是看不到系統(tǒng)孵化出來的進程的。也就是我們常見的為什么有些代碼打不上斷點。

追過startActivity()的同學(xué),應(yīng)該很熟悉下邊這個調(diào)用流程,跟進幾個方法之后就發(fā)現(xiàn)進到了一個叫做ActivityTread的類里邊。

ActivityTread這個類有什么特點?有main函數(shù),就是我們的主線程。

很快我們能看到一個比較常見類的調(diào)用:Instrumentation:

  1. // Activity.java 
  2. public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { 
  3.     mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options); 
  4.     // 省略 

注意mInstrumentation#execStartActivity()有一個標黃的入?yún)ⅲ茿ctivityThread中的內(nèi)部類ApplicationThread。

ApplicationThread這個類有什么特點,它實現(xiàn)了IApplicationThread.Stub,也就是aidl的“跨進程調(diào)用的客戶端回調(diào)”。

此外mInstrumentation#execStartActivity()中又會看到一個大名鼎鼎的調(diào)用:

  1. public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { 
  2.     // 省略... 
  3.     ActivityManager.getService() 
  4.         .startActivity(whoThread, who.getBasePackageName(), intent, 
  5.                 intent.resolveTypeIfNeeded(who.getContentResolver()), 
  6.                 token, target != null ? target.mEmbeddedID : null
  7.                 requestCode, 0, null, options); 
  8.     return null

我們點擊去getService()會看到一個標紅的IActivityManager的類。

它并不是一個.java文件,而是aidl文件。

所以ActivityManager.getService()本質(zhì)返回的是“進程的服務(wù)端”接口實例,也就是:

ActivityManagerService

public class ActivityManagerService extends IActivityManager.Stub

所以執(zhí)行到這就轉(zhuǎn)到了系統(tǒng)進程(system_process進程)。省略一下代碼細節(jié),看一下調(diào)用棧:

從上述debug截圖,看一看到此時已經(jīng)拿到了我們的目標Activitiy的相關(guān)信息。

這里簡化一些獲取目標類的源碼,直接引入結(jié)論:

PackageManagerService

這里類相當于解析手機內(nèi)的所有apk,將其信息構(gòu)造到內(nèi)存之中,比如下圖這樣:

小tips:手機目錄中/data/system/packages.xml,可以看到所有apk的path、進程名、權(quán)限等信息。

啟動新進程

打開目標Activity的前提是:目標Activity的進程啟動了。所以第一次想要打開目標Activity,就意味著要啟動進程。

啟動進程的代碼就在啟動Activity的方法中:

resumeTopActivityInnerLocked->startProcessLocked。

這里便引入了另一個另一個大名鼎鼎的類:ZygoteInit。這里簡單來說會通過ZygoteInit來進行App進程啟動的。

ApplicationThread

進程啟動后,繼續(xù)回到目標Activity的啟動流程。這里依舊是一系列的system_process進行的轉(zhuǎn)來轉(zhuǎn)去,然后IApplicationThread進入目標進程。

注意看,在這里再次通過IApplicationThread回調(diào)到ActivityThread。

  1. class H extends Handler { 
  2.     // 省略 
  3.     public void handleMessage(Message msg) { 
  4.         switch (msg.what) { 
  5.             case EXECUTE_TRANSACTION: 
  6.                 final ClientTransaction transaction = (ClientTransaction) msg.obj; 
  7.                 mTransactionExecutor.execute(transaction); 
  8.                 // 省略 
  9.                 break; 
  10.             case RELAUNCH_ACTIVITY: 
  11.                 handleRelaunchActivityLocally((IBinder) msg.obj); 
  12.                 break; 
  13.         } 
  14.         // 省略... 
  15.     } 
  16.  
  17. // 執(zhí)行Callback 
  18. public void execute(ClientTransaction transaction) { 
  19.     final IBinder token = transaction.getActivityToken(); 
  20.     executeCallbacks(transaction); 

這里所謂的CallBack的實現(xiàn)是LaunchActivityItem#execute(),對應(yīng)的實現(xiàn):

  1. public void execute(ClientTransactionHandler client, IBinder token, 
  2.         PendingTransactionActions pendingActions) { 
  3.     ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo, 
  4.             mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState, 
  5.             mPendingResults, mPendingNewIntents, mIsForward, 
  6.             mProfilerInfo, client); 
  7.     client.handleLaunchActivity(r, pendingActions, null); 

此時就轉(zhuǎn)到了ActivityThread#handleLaunchActivity(),也就轉(zhuǎn)到了咱們?nèi)粘5纳芷诶镞叄{(diào)用棧如下:

上述截圖的調(diào)用鏈中暗含了Activity實例化的過程(反射):

  1. public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className, @Nullable Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException { 
  2.  
  3.     return (Activity) cl.loadClass(className).newInstance(); 
  4.  

瀏覽器啟動原理

Helo站內(nèi)的回流頁就是一個標準的,瀏覽器喚起另一個App的實例。

交互流程

html標簽有一個屬性href,比如:。

我們常見的一種用法:。也就是點擊之后跳轉(zhuǎn)到百度。

因為這個是前端的標簽,依托于瀏覽器及其內(nèi)核的實現(xiàn),跳轉(zhuǎn)到一個網(wǎng)頁似乎很“順其自然”(不然叫什么瀏覽器)。

當然這里和android交互的流程基本一致:用隱式調(diào)用的方式,聲明需要啟動的Activity;然后傳入對應(yīng)的協(xié)議(scheme)即可。比如:

前端頁面:

  1. <head> 
  2.   <meta charset="UTF-8"
  3.   <meta name="viewport" content="width=device-width, initial-scale=1.0"
  4. </head> 
  5. <body> 
  6. <a href="mdove1://haha"> 啟動OtherActivity </a> 
  7. </body> 

android聲明:

  1. <activity 
  2.     android:name=".OtherActivity" 
  3.     android:screenOrientation="portrait"
  4.     <intent-filter> 
  5.         <data 
  6.             android:host="haha" 
  7.             android:scheme="mdove1" /> 
  8.         <action android:name="android.intent.action.VIEW" /> 
  9.         <category android:name="android.intent.category.BROWSABLE" /> 
  10.         <category android:name="android.intent.category.DEFAULT" /> 
  11.     </intent-filter> 
  12. </activity> 

推理實現(xiàn)

瀏覽器能夠加載scheme,可以理解為是瀏覽器內(nèi)核做了封裝。那么想要讓android也能支持對scheme的解析,難道是由瀏覽器內(nèi)核做處理嗎?

很明顯不可能,做了一套移動端的操作系統(tǒng),然后讓瀏覽器過來實現(xiàn),是不是有點殺人誅心。

所以大概率能猜測出來,應(yīng)該是手機中的瀏覽器app做的處理。我們就基于這個猜想去看一看瀏覽器.apk的實現(xiàn)。

瀏覽器實現(xiàn)

基于上邊說的/data/system/packages.xml文件,我們可以pull出來瀏覽器的.apk。

然后jadx反編譯一下Browser.apk中WebView相關(guān)的源碼:

我們可以發(fā)現(xiàn)對href的處理來自于隱式跳轉(zhuǎn),所以一切就和上邊的流程串了起來。

尾聲

 

結(jié)尾留個小問題:如果我自己寫個WebView去load一個前端頁面,能隱式跳轉(zhuǎn)嗎?

 

責(zé)任編輯:武曉燕 來源: 咸魚正翻身
相關(guān)推薦

2017-07-20 14:13:38

前端瀏覽器Native App

2012-06-04 10:35:55

FirefoxChrome瀏覽器

2011-02-22 09:50:21

2024-04-10 09:05:37

2019-02-13 23:03:06

IE瀏覽器微軟

2022-02-28 21:15:42

火狐火狐瀏覽器瀏覽器

2021-08-30 09:57:40

2009-06-15 08:37:08

微軟Windows 7操作系統(tǒng)

2016-08-18 14:29:21

瀏覽器Vendor Prefvendor-pref

2021-08-06 10:10:47

Safari開發(fā)者瀏覽器

2013-01-11 09:51:03

瀏覽器

2009-03-23 08:52:51

2022-01-04 21:36:33

JS瀏覽器設(shè)計

2010-04-05 21:57:14

Netscape瀏覽器

2009-03-04 11:16:03

RABSoft瀏覽器控制電腦

2017-01-05 18:57:19

2012-03-20 11:31:58

移動瀏覽器

2012-03-20 11:41:18

海豚瀏覽器

2012-03-19 17:25:22

2012-03-20 11:07:08

點贊
收藏

51CTO技術(shù)棧公眾號

黄色av免费观看| 国产特黄级aaaaa片免| 精品黑人一区二区三区观看时间| 国产高清自拍视频在线观看| 免费在线一区观看| 久久手机免费视频| 国内精品免费视频| 中文不卡1区2区3区| 中文字幕欧美激情| av在线不卡一区| 精品美女久久久久| 久久人人99| 精品国偷自产国产一区| 国产无套粉嫩白浆内谢的出处| 免费高清在线观看| www.欧美.com| 国产在线观看不卡| 99精品视频99| 我不卡神马影院| 日韩国产高清视频在线| 思思久久精品视频| a欧美人片人妖| 日韩久久一区二区| 鲁片一区二区三区| 一级黄色大片网站| 国产一区日韩一区| 亚洲福利精品在线| 亚洲精品手机在线观看| 美女av在线免费看| 亚洲伦在线观看| 日本一区二区三区视频在线观看| 亚洲AV无码精品自拍| 日韩av网站在线观看| 欧美丰满片xxx777| 精品少妇一区二区三区密爱| 欧美高清视频看片在线观看| 5566中文字幕一区二区电影| 哪个网站能看毛片| 大香伊人久久| 亚洲免费在线视频一区 二区| 欧美主播一区二区三区美女 久久精品人| 99热这里只有精品3| 久久久久久久高潮| 国内精品视频一区| 永久免费看黄网站| 99精品视频精品精品视频| 亚洲精品一区二三区不卡| 亚洲在线观看网站| 豆花视频一区| 欧美日韩高清影院| 男女污污的视频| 天堂在线中文网官网| 一区二区免费看| 在线视频一二三区| 香蕉视频网站在线观看| av高清久久久| 国产精品综合久久久久久| 中文字幕视频二区| 日本亚洲最大的色成网站www| 欧美在线视频免费播放| 黄色片视频网站| 亚洲经典三级| 欧美一级大片视频| 国产精品日日夜夜| 在线看片成人| 欧美激情小视频| 国产精品成人免费观看| 亚洲一区在线| 美日韩精品视频免费看| 三级全黄做爰视频| 亚洲综合自拍| 久久99国产精品自在自在app| 手机在线免费看毛片| 91高清一区| 欧美裸身视频免费观看| 久草成人在线视频| 亚洲少妇一区| 国产精品极品美女在线观看免费 | 欧美国产亚洲另类动漫| 欧美日韩一区二区视频在线观看| 你懂的在线网址| 97se亚洲国产综合在线| 欧美二区三区在线| 欧美xxx.com| 国产精品久久久久影院老司| 日韩视频在线观看视频| 丰乳肥臀在线| 欧美日韩精品在线观看| 欧美黄色一级片视频| 欧美日韩女优| 欧美一二三四在线| 成人在线视频免费播放| 深爱激情综合网| 日韩色av导航| a v视频在线观看| 日韩av一区二区三区| 18成人在线| 日本亚洲一区| 亚洲欧美日韩精品久久久久| 欧美极品少妇无套实战| 东京一区二区| 日韩一区二区三区四区五区六区| 182在线视频| 青青一区二区三区| 久久久久在线观看| 国产女优在线播放| 国产成人午夜高潮毛片| 欧美日韩喷水| 在线观看电影av| 91久久线看在观草草青青 | 国产精品456露脸| 久久精品人成| 黄色动漫在线| 色综合久久久久综合体桃花网| xxx国产在线观看| 国产主播性色av福利精品一区| 伊人一区二区三区久久精品| 男女做暖暖视频| 亚洲欧美日韩国产一区二区| 国产日韩中文在线| 日本亚洲欧美| 亚洲国产日韩在线一区模特| 手机在线免费观看毛片| 国产图片一区| 久久成人av网站| 无码人妻精品一区二区三区蜜桃91| 国产精品中文欧美| 视频三区二区一区| 高清精品在线| 欧美不卡一区二区三区四区| 一级片黄色录像| 亚洲一级影院| 99久久无色码| 日本在线观看免费| 欧洲精品中文字幕| 亚洲成人av免费在线观看| 欧美第一精品| 欧美亚洲视频在线观看| 丰满人妻一区二区三区四区53| 国产精品美女一区二区| 日韩在线xxx| 日本成人中文| 韩国美女主播一区| 亚洲国产成人在线观看| 日韩一区在线免费观看| 日韩一区二区三区不卡视频| 精品自拍偷拍| 孩xxxx性bbbb欧美| 成 人 黄 色 片 在线播放 | 日本一区二区久久精品| 乡村艳史在线观看| 亚洲精品97久久| 青娱乐在线视频免费观看| 精一区二区三区| 综合操久久久| 欧美视频二区欧美影视| 欧美成年人视频网站| 99久久久无码国产精品免费| ...av二区三区久久精品| 中文字幕永久有效| 91精品99| 亚洲淫片在线视频| 9191在线播放| 精品国产乱码久久| 国产精品白浆一区二小说| 成人国产精品视频| 男人添女人下面高潮视频| 久久九九热re6这里有精品| 亚州av一区二区| 三级av在线播放| 在线精品国精品国产尤物884a| 国产精品天天干| 久热成人在线视频| 一二三四中文字幕| 精品国产影院| 欧美一级淫片丝袜脚交| 国产美女视频一区二区三区| 在线观看日韩国产| 妖精视频在线观看免费| 国产精品综合二区| av网站手机在线观看| 国产精品香蕉| 国产精品99久久久久久www| 免费观看在线黄色网| 精品久久五月天| 可以免费在线观看的av| 国产三级三级三级精品8ⅰ区| 999在线免费视频| 中文字幕一区二区三区久久网站| 国产激情一区二区三区在线观看| 精精国产xxxx视频在线播放| 一本色道久久88精品综合| 国产精品久久影视| 亚洲电影一级黄| 摸摸摸bbb毛毛毛片| 国产在线精品不卡| 久久99久久久久久| 久久99免费视频| 国产精品一区二区久久久久| 久久99精品久久久久久野外| 精品福利一二区| 涩涩视频在线观看| 亚洲不卡av一区二区三区| 蜜桃久久精品成人无码av| 国产高清一区日本| 超碰影院在线观看| 国产精品v亚洲精品v日韩精品 | 成人高清av| 国产精品国产精品| 精品视频一区二区三区四区五区| 欧美成人精品三级在线观看| 美国一级片在线免费观看视频 | 日韩中文字幕免费在线观看| 在线亚洲免费视频| www.天天色| 中文字幕一区二区日韩精品绯色| japanese在线观看| 可以看av的网站久久看| 日韩国产精品毛片| 国产精品免费大片| 国产精品乱码视频| 欧美h版在线观看| 国产精品美女无圣光视频| 黄毛片在线观看| 久久国产精品影视| 91官网在线| 亚洲性生活视频| 神马久久久久久久久久| 欧美一区二区在线看| 波多野结衣在线观看一区| 亚洲.国产.中文慕字在线| 成人在线观看小视频| 中文一区二区在线观看| 亚洲人人夜夜澡人人爽| 成人一区二区三区中文字幕| 污污网站免费看| 国产一区二区三区的电影| 青青草视频在线视频| 99久久精品费精品国产| 欧美综合77777色婷婷| 香蕉视频一区| 国产日韩在线一区二区三区| 美女久久精品| 亚洲一区二区少妇| 78精品国产综合久久香蕉| 日本欧美在线视频| 韩日精品一区二区| 欧美亚洲成人xxx| 美女露胸视频在线观看| 亚州精品天堂中文字幕| 丁香影院在线| 欧美寡妇偷汉性猛交| 免费黄色网址在线观看| 中文字幕欧美在线| 黄色在线播放| 亚洲美女动态图120秒| 国产成人精品白浆久久69| 91精品国产乱码| 国产片在线播放| 欧美va亚洲va| 亚洲国产剧情在线观看| 精品国产三级a在线观看| 风流少妇一区二区三区91| 欧美成va人片在线观看| 狠狠人妻久久久久久综合麻豆 | 天堂a√在线| 亚洲精品在线不卡| 亚洲欧美自偷自拍| 亚洲天堂久久av| 91亚洲欧美| 久久人人爽亚洲精品天堂| а√天堂官网中文在线| 欧美日本高清一区| 韩日毛片在线观看| 国产精品99导航| 高清不卡一区| 国产伦一区二区三区色一情| 美女福利视频在线观看| 99视频精品全部免费在线| 欧美双性人妖o0| 久久一留热品黄| 女~淫辱の触手3d动漫| 国产欧美日韩另类一区| 永久免费看片直接| www.豆豆成人网.com| 久久九九免费视频| 污污视频在线看| 97在线观看视频国产| 欧美成人精品一区二区男人小说| 国产精品日韩在线| 日韩精品三级| 欧美精品在线一区| 欧美日韩国产高清电影| 亚洲天堂电影网| 亚洲欧美网站在线观看| 无码专区aaaaaa免费视频| 老牛嫩草一区二区三区日本 | 白浆在线视频| 国产精品久久久久久一区二区| 625成人欧美午夜电影| 成人精品久久av网站| 免费观看成人www动漫视频| 手机看片福利永久国产日韩| 欧美激情五月| 无人在线观看的免费高清视频| 国产成人精品免费一区二区| 亚洲男女在线观看| 日韩一区中文字幕| 免费污污视频在线观看| 日韩欧美亚洲国产另类| 日韩a在线看| 久久九九国产精品怡红院| 成人直播视频| 国产麻豆一区二区三区在线观看| 欧美日韩一区二区综合| 男女日批视频在线观看| 老汉av免费一区二区三区| 久久无码人妻精品一区二区三区| 亚洲图片欧美激情| 91porny九色| 亚洲第一精品久久忘忧草社区| 日本亚洲精品| 国产成人在线一区| 欧美大胆a级| 欧美爱爱视频网站| 欧美专区一区二区三区| ass极品水嫩小美女ass| 中文字幕av一区二区三区| 日韩免费不卡视频| 91精品福利在线一区二区三区 | 国产高清不卡无码视频| 日韩不卡一二三区| www.色多多| 午夜伦欧美伦电影理论片| www.av网站| 超薄丝袜一区二区| 亚洲伦理一区二区| 欧美不卡在线一区二区三区| 在线免费观看日本欧美爱情大片| 日本999视频| 久久先锋影音av| 日韩污视频在线观看| 精品999在线播放| 日韩av毛片| 99久久99| 激情文学一区| 少妇伦子伦精品无吗| 亚洲欧美日韩国产手机在线| 午夜精品久久久久久久蜜桃app| 五月天激情国产综合婷婷婷| 日韩精品视频在线播放| 美女91在线看| 欧美综合激情| 麻豆成人综合网| 久久精品一区二区三区四区五区| 欧美精品丝袜中出| а√天堂官网中文在线| 草莓视频一区| 中文久久精品| 蜜桃传媒一区二区亚洲| 欧美片网站yy| 欧美videossex另类| 精品国产一区二区三区免费| 香蕉亚洲视频| 女人18毛片毛片毛片毛片区二| 日韩色在线观看| 欧美gv在线观看| 亚洲成人在线视频网站| 国产一区在线精品| 日产欧产va高清| 亚洲最新av在线网站| 国产在线不卡一区二区三区| 日韩久久久久久久久久久久| 91美女片黄在线观看91美女| 中文字字幕在线观看| 欧美另类极品videosbest最新版本| 欧美一性一交| 日韩肉感妇bbwbbwbbw| 亚洲乱码日产精品bd| 水中色av综合| 成人精品视频99在线观看免费| 亚洲精品1234| 国产免费嫩草影院| 亚洲第一精品久久忘忧草社区| 欧美日韩精品一区二区三区视频| 久久久久久久久久久久久国产| 91在线看国产| 一区二区日韩视频| 国外成人性视频| 91一区二区| 变态另类丨国产精品| 欧美精品久久天天躁| 理论不卡电影大全神| 一级全黄肉体裸体全过程| 99re66热这里只有精品3直播| 一区不卡在线观看| 日本中文字幕久久看| 中文字幕一区二区三三| 日本二区在线观看| 亚洲国产一区二区三区四区|