contentprovider 是Android開發四大元件之一,最大的用途一般是用來誇程序共享資料。而在很多第三方熱門開源架構中用他來進行初始化操作,代替再Application的onCreate()中添加init()方法,這樣做的好處解耦,例如Glide圖檔庫的初始化,leakcanary的初始化。原理如下:
makeApplication() 調用鍊:
>
LoadedApk#makeApplication() -> Instrumentation#newApplication() -> Instrumentation.newApplication() -> Application#attach() -> Application#attachBaseContext()
installContentProviders() 調用鍊:
>
ActivityThread#installContentProviders() -> ActivityThread#installProvider() -> ContentProvider#attachInfo() -> ContentProvider.this.onCreate()
callApplicationOnCreate 調用鍊:
>
Instrumentation#callApplicationOnCreate() -> Application#onCreate()
如上,contentprvoider 的初始化介于Application的 attachBaseContext()方法,和onCreate()方法之間。确實可以做到自動初始化。但是contentprovider 初始化也是有缺點的。
網上說的最多也是能查到的确定是,如果某些初始化依賴别的庫,那麼必須要在别的庫初始化之後進行初始化,不能魯莽的采用。要清楚調用結構。
沒有提到的卻是個人認為最為重要的一點,也是這篇文章想說的中心點:
在多程序的APP啟動流程中,慎用ContentProvider
<provider
android:name="com.aisino.interconnect.contentprovider.InitLibraryProvider"
android:exported="false"
android:authorities="${applicationId}.initlibrary"
android:multiprocess="true"/>
四大元件要在清單檔案中注冊,注意屬性 multiprocess 和 process
1. android:process=":fore",android:multiprocess="true":provider不會随應用的啟動而加載,當調用到provider的時候才會加載,加載時provider是在調用者的程序中初始化的。這時候可能定義provider的fore程序還沒有啟動。
2. android:process=":fore"(android:multiprocess預設情況下為"false"):provider不會随應用的啟動而加載,當調用到provider的時候才會加載,加載時provider是在“fore”程序中初始化的。
3. android:multiprocess="true":provider會随着應用啟動的時候加載,加載時provider是在應用預設主程序中初始化的。對于android:multiprocess=true,意味着provider可以多執行個體,那麼由調用者在自己的程序空間執行個體化一個ContentProvider對象,此時定義ContentProvider的App可能并沒有啟動。
4. android:multiprocess="false":provider會随着應用啟動的時候加載,加載時provider是在應用預設主程序中初始化的。對于android:multiprocess=false(預設值),由系統把定義該ContentProvider的App啟動起來(一個獨立的Process)并執行個體化ContentProvider,這種ContentProvider隻有一個執行個體,運作在自己App的Process中。所有調用者共享該ContentProvider執行個體,調用者與ContentProvider執行個體位于兩個不同的Process。
看清楚流程之後總結一點,對于定義contentprovider 的APP 不管有幾個程序,隻初始化一次,onceate隻執行一次,當multiprocess為true,有多個執行個體的意思,是代表不同的程序調用可以有多個遠端binder執行個體!概念不要混淆!!!
是以針對在contentprovider 中 初始化應用,結合上文分析可以得知,非常重要的一點,如果應用存在多程序,且對程序中對某些資源都要單獨執行個體化的情況下,禁止使用contentProvider初始化,在application 中初始化。其他的時候可以使用。
查詢指令記錄 查詢應用程序資訊
adb shell ps adb shell ps grep | "篩選條件"