文章

ContentProvider 中做应用初始化

ContentProvider 中做应用初始化

ContentProvider 中做应用初始化

在 ContentProvider 中做应用初始化

  • 原理
    我们都知道 ContentProvider 的 onCreate 的调用时机介于 Application 的 attachBaseContext 和 onCreate 之间,Provider 的 onCreate 优先于 Application 的 onCreate 执行,并且此时的 Application 已经创建成功,而 Provider 里的 context 正是 Application 的对象,Lifecycle 这么做,把 init 的逻辑放到库内部,让调用方完全不需要在 Application 里去进行初始化了,十分方便。
  • 定义 ContentProvider
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
internal class DebugToolsProvider : ContentProvider() {

    override fun onCreate(): Boolean {
        Log.i(DebugTools.TAG, "[DebugToolsProvider onCreate]" +
                "run adb shell am broadcast -a club.jinmei.mgvoice.debug to install DebugTools")
        context.registerReceiver(object : BroadcastReceiver() {
            var installed: Boolean = false
            override fun onReceive(context: Context?, intent: Intent?) {
                if (!installed) {
                    DebugTools.init(context!!)
                    Toast.makeText(context, "debug tools初始化", Toast.LENGTH_SHORT)
                            .show()
                    installed = true
                } else {
                    Toast.makeText(context, "debug tools已开启了,不要重复初始化", Toast.LENGTH_LONG)
                            .show()
                }
            }
        }, IntentFilter("club.jinmei.mgvoice.debug"))
        return true
    }

    override fun query(uri: Uri, projection: Array<String>?, selection: String?, selectionArgs: Array<String>?, sortOrder: String?): Cursor? {
        return null
    }

    override fun getType(uri: Uri): String? {
        return null
    }

    override fun insert(uri: Uri, values: ContentValues?): Uri? {
        return null
    }

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
        return 0
    }

    override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<String>?): Int {
        return 0
    }

}
  • 清单文件注册
    使用 ContentProvider 初始化的方式,我们需要注意一下几点:
    首先,在 Manifest 里设置 ContentProvider 的时候要设置一个 authorities,这个 authorities 相当于 ContentProvider 的标识,是不能重复的,为了保证不重复,我们再设置这个值的时候最好不要硬编码,而是使用以下的这种方式:使用 appid+xxx
1
2
3
4
5
6
<application>
    <provider
            android:name=".DebugToolsProvider"
            android:authorities="${applicationId}.debugtools.autopilot"
            android:exported="false" />
</application>

使用 ContentProvider 初始化的库

Ref

本文由作者按照 CC BY 4.0 进行授权