因為Activity的特殊性,activity的class被classLoader加載之后是可以當普通類使用了,但是生命周期需要系統(tǒng)回調(diào)。而且activity的啟動過程比較復雜,不是一個簡單的類加載和反射的過程。
為實現(xiàn)Activity的生命周期,實現(xiàn)方案都需要預先在宿主中占位,插件化技術發(fā)展到現(xiàn)在,為了輕量化,目前主流的實現(xiàn)方案有兩種:
- 替換Class loader
- 替換Instrumentation
Activity啟動過程
要實現(xiàn)這兩種方案,先要了解Activity的啟動過程

Activity_start.png
- AMS: 即ActivityManagerServices,服務端對象,負責系統(tǒng)中所有Activity的生命周期
- ActivityThread:App的入口,當開啟App之后,會調(diào)用main()開始運行,開啟消息循環(huán)隊列。就是主線程。
與ActivityManagerServices配合,一起完成Activity的管理工作。 - Instrumentation: 應用內(nèi)單實例對象,負責Activity的創(chuàng)建和暫停
- ApplicationThread:負責ActivityManagerService與ActivityThread之間的交互。在ActivityManagerService需要管理相關Application中的Activity的生命周期時,通過ApplicationThread的代理對象與ActivityThread通訊
- ApplicationThreadProxy: ApplicationThread在服務器端的代理,負責和客戶端的ApplicationThread通訊。AMS就是通過該代理與ActivityThread進行通信的
- ActivityStack:Activity在AMS的棧管理,用來記錄已經(jīng)啟動的Activity的先后關系,狀態(tài)信息等。通過ActivityStack決定是否需要啟動新的進程
啟動流程簡述
- 先通過Instrumentation檢查對應的Activity是否已經(jīng)啟動,若已經(jīng)啟動切符合條件則直接返回。沒有在調(diào)用AMS去啟動activity
- AMS調(diào)用ActivityStarter啟動Activity。ActivityStarter先解析Intent中Activity的信息。查詢系統(tǒng)中是否有符合要求的Activity
- 使用合適的ActivityStack和 launch flags 來啟動 Activity, 如果存在可以直接恢復 Activity,則恢復,否則重新啟動 Activity
- 如果此時Activity所在的App未啟動,則先創(chuàng)建對應的App進程
- 若要啟動新的Activity,AMS會通過binder調(diào)用App進程,使用 ActivityThread 去執(zhí)行啟動,
- Instrumentation對過反射生成Activity的實例
- 使用handler來調(diào)用新生成的Activity的生命周期
替換Class loader
實現(xiàn)過程
- 自定義一個PathClassLoader,App啟動時將自定義的ClassLoader替換系統(tǒng)的ClassLoader
- 解析啟動插件Activity的intent,找到插件中對應的Activity class
- 分配與要啟動的Activity的啟動方式一致的坑位Activity,并保持兩個Activity的關聯(lián)
- 讓系統(tǒng)啟動坑位的Activity, 系統(tǒng)會使用替換過的ClassLoader加載坑位的Activity
- 替換過的ClassLoader啟動坑位的Activity時,通過對應的關聯(lián)找到對應的插件中的activity,
找到后加載并返回 - android系統(tǒng)拿到的Activity就是插件中的activity, 然后調(diào)用它的生命周期
替換Instrumentation
這個方案比較簡單和輕量,由于activity的啟動和反射都是在Instrumentation中進行的,所以只hook啟動和反射生成實例的程就可以將占位的activity替換為插件中的Activity
實現(xiàn)過程
- 封裝一個Instrumentation,重寫啟動Activity的方法
- 將啟動的插件中的Activity替換為占位的activity
- 重寫Instrumentation的newActivity方法,使用插件的class loader 反射生成插件的activity
- 然后將封裝的Instrumentation替換掉宿主中的Instrumentation
這樣宿主啟動的acticity最終被替換成了插件中的activity,生命周期完全由系統(tǒng)管理。
但是由于啟動方式多樣性,所以占坑的時候需要埋入比較多的占坑Acttivity來應對不同的啟動方式
這個方案的過程比較簡單,而且hook的點很少,所以很輕量