參考:
A
B
我們做項(xiàng)目的時(shí)候會(huì)用到很多庫(kù),不論是三方庫(kù)還是或者是自己寫(xiě)的,不可避免的會(huì)要去初始化它們,一般都是在Application的oncreate里,那么我們現(xiàn)在會(huì)在Application里這么寫(xiě):
@Override
public void onCreate() {
super.onCreate();
MyLib.init(this);
}
通過(guò)init方法傳遞一個(gè)Application進(jìn)去并持有它。
這樣做沒(méi)什么錯(cuò),但是在我看來(lái)是不太好的。
如果你使用過(guò)Lifecycle或者Firebase,你會(huì)發(fā)現(xiàn)你根本不用寫(xiě)哪怕一行的初始化代碼就可以使用它,那么它們是怎么做的呢?
以Lifecycle為例:
我們?nèi)タ碙ifecycle的Manifest,其中會(huì)注冊(cè)一個(gè)ContentProvider:
<provider
android:name="android.arch.lifecycle.LifecycleRuntimeTrojanProvider"
android:authorities="xx.xx.xxxx.lifecycle-trojan"
android:exported="false"
android:multiprocess="true" />
而這個(gè)Provider的實(shí)現(xiàn)非常的簡(jiǎn)單:
public class LifecycleRuntimeTrojanProvider extends ContentProvider {
@Override
public boolean onCreate() {
LifecycleDispatcher.init(getContext());
ProcessLifecycleOwner.init(getContext());
return true;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, String[] strings, String s, String[] strings1,
String s1) {
return null;
}
...
//return null or 0;
}
原理:我們都知道ContentProvider的onCreate的調(diào)用時(shí)機(jī)介于Application的attachBaseContext和onCreate之間,Provider的onCreate優(yōu)先于Application的onCreate執(zhí)行,并且此時(shí)的Application已經(jīng)創(chuàng)建成功,而Provider里的context正是Application的對(duì)象,Lifecycle這么做,把init的邏輯放到庫(kù)內(nèi)部,讓調(diào)用方完全不需要在Application里去進(jìn)行初始化了,十分方便。
注意點(diǎn):
使用ContentProvider初始化的方式,我們需要注意一下幾點(diǎn):
首先,在Manifest里設(shè)置ContentProvider的時(shí)候要設(shè)置一個(gè)authorities,這個(gè)authorities相當(dāng)于ContentProvider的標(biāo)識(shí),是不能重復(fù)的,為了保證不重復(fù),我們?cè)僭O(shè)置這個(gè)值的時(shí)候最好不要硬編碼,而是使用以下的這種方式:使用appid+xxx
<provider
android:authorities="${applicationId}.xxprovider"
android:name=".MyLibRuntimeProvider"
android:exported="false"/>
由ActivityThread的handleBindApplication方法可以看到,是先調(diào)用installContentProviders方法,然后調(diào)用mInstrumentation.callApplicationOnCreate方法的。