注册

你的Android库是否还在Application中初始化?

通常来说,当我们引入一个第三方库,第一件要做的事情是在Application中的onCreate传入context初始化这个库 😞。但是为什么像一些库如Firebase🔥,初始化的时候并不需要在Application中初始化呢?今天我们就来探索一下这个问题 🧐


Android库的初始化


举个栗子,我们需要在app中国呢使用ARouter,在使用前需要初始化传入context,因此如果没有application时我们要创建一个:


class MainApplication : Application() {
override fun onCreate(){
super.onCreate()
ARouter.init(mApplication);
}
}
复制代码

然后要在清单文件 AndroidManifest.xml 中声明才会执行 :


<application
android:name=".MainApplication"
...
复制代码

更多库怎么办


现在想象我们使用了ARouter,友盟统计,Realm,ToastUtils等库时,我们的application可能会是如下形式:


class MainApplication : Application() {
override fun onCreate(){
super.onCreate()
ARouter.init(this)
UMConfigure.init(this,...)
Realm.init(this)
ToastUtils.init(this)
}
}
复制代码

在项目中, 仅仅为了初始化一些库,我就必须得新建Application并且在onCreate中调用它。(译者:也许你认为这也没什么,但是如果你自己创建了多个库需要context时,你每次得预留一个init方法暴露给调用者,使用时又得在application初始化。)



Useless


无需“初始化”的库


如果你的项目加入了Firebase 🔥, 你会发现它并没有要求初始化, 你只要使用它 :

1


这个数据库访问没有需要context的传入,通过离线访问存储本地。可以猜测它有一个机制获取上下文application context,自动完成初始化。


ContentProvider & Manifest-Merger


developer.android.com/studio/buil…



你的Apk文件只包含一个清单文件AndroidManifest.xml,但是你的Android Studio项目可能会有多个源集(main source set),构建变体(build variants),导入的库(imported libraries)构成。因此在编译构建app时,gradle插件会将多个manifest文件合并到一个清单文件中去。



我们可以看下合并后的清单文件(目录如下):



app/build/intermediates/merged_manifests/MY_APP/processMY_APPDebugManifest/merged/AndroidManifest.xml



我们可以发现一个关于Firebase库的provider被引入到清单文件中:

1


使用Android Studio点击打开FirebaseInitProvider, 我们知道了这个provider通过this.getContext()来访问上下文。

内容提供者ContentsProviders会直接在Application创建后完成初始化,因此通过它来完成library的初始化不失为一个好办法。

1


自动初始化我们的库


如果我们自定义了ToastUtils库需要初始化,我们自己提供一个Provider :


class ToastInitProvider : ContentProvider() {

override fun onCreate(): Boolean {
ToastUtils.init(context)
return true
}
...
}
复制代码

然后这个库中的AndroidManifest.xml中加入它


<provider
android:name=".ToastInitProvider"
android:authorities="xxx.xx.ToastInitProvider" />
复制代码

然后当我们使用这个ToastUtils库时,无需添加额外的代码在项目中初始化它😎,直接使用它即可:


ToastUtils.show("this is toast")
复制代码
Stetho.getInstance().configure(…)
复制代码

删除Application


如果一些库没有使用InitProviders,我们可以创建它:


class ARouterInitProvider : ContentProvider() {

override fun onCreate(): Boolean {
ARouter.init(this)
return true
}
...
}
class RealmInitProvider : ContentProvider() {

override fun onCreate(): Boolean {
Realm.init(this)
return true
}
...
}
复制代码

然后加入到清单文件AndroidManifest中 :


<provider
android:name=".ARouterInitProvider"
android:authorities="${applicationId}.ARouterInitProvider" />
<provider
android:name=".RealmInitProvider"
android:authorities="${applicationId}.RealmInitProvider" />
复制代码

现在我们可以 移除 这个 MainApplication


Happy Dance


项目地址


https://github.com/florent37/ApplicationProvider

作者:星星y
链接:https://juejin.cn/post/6844903967864913933
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册