美文网首页
[奇技淫巧]使用ContentProvider初始化三方库

[奇技淫巧]使用ContentProvider初始化三方库

作者: HanderWei | 来源:发表于2019-07-16 12:25 被阅读0次

在聊这个话题之前,先聊一下Lifecycle。

熟悉Lifecycle的人应该知道,Activity分发生命周期事件是通过LifecycleDispatcherProcessLifecycleOwner实现的,而这两个类的初始化都是在ProcessLifecycleOwnerInitializer中进行初始化的。

public class ProcessLifecycleOwnerInitializer extends ContentProvider {
    @Override
    public boolean onCreate() {
        LifecycleDispatcher.init(getContext());
        ProcessLifecycleOwner.init(getContext());
        return true;
    }
}

ProcessLifecycleOwnerInitializer实际上是一个ContentProvider,ContentProvider会在应用初始化的时候回调onCreate方法,Lifecycle的设计者正是借鉴这一特性在ContentProvider做了初始化。

不熟悉Lifecycle的同学也不要慌,可以看看这篇博文,讲的很详细:Lifecycle源码分析 | Kyleduo's blog!

那么Lifecycle是如何在我们的app中注册这个ContentProvider的呢?毕竟我们可没在app的AndroidManifest文件中注册这个ContentProvider。

打开打包生成的apk文件,查看AndroidManifest.xml,可以找到:

<provider
    android:name="android.arch.lifecycle.ProcessLifecycleOwnerInitializer"
    android:exported="false"
    android:multiprocess="true"
    android:authorities="dev.chenwei.livedatademo.lifecycle-trojan" />

想必是在extensions库中注册的这个ContentProvider。

查看android.arch.lifecycle:extensions的aar,打开AndroidManifest文件

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.arch.lifecycle.extensions" >

    <uses-sdk android:minSdkVersion="14" />

    <application>
        <provider
            android:name="android.arch.lifecycle.ProcessLifecycleOwnerInitializer"
            android:authorities="${applicationId}.lifecycle-trojan"
            android:exported="false"
            android:multiprocess="true" />
    </application>

</manifest>

这里还使用了${applicationId}占位符,避免authroities冲突。


既然Lifecycle的设计者通过ContentProvider完成初始化,那么其他三方库是不是可以借鉴这一思想,更进一步的简化三方库的注入呢?

我们同样可以定义一个ContentProvider,在onCreate方法中做初始化操作:

class LibraryInitializer: ContentProvider() {

    override fun onCreate(): Boolean {
        // 可以拿到ApplicationContext进行有些初始化操作
        return true
    }
    
    override fun insert(uri: Uri, values: ContentValues?): Uri? {
        return null
    }

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

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

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

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

}

然后在Module内部的AndroidManifest.xml中注册该ContentProvider即可。

PS:国外一大神在16年就发现了这一奇技淫巧 Auto-initialize your android library - André Tietz - Medium

在文章中还提出了applicationId没有配置的兜底方案,并且讨论了使用该方案的弊端。

相关文章

网友评论

      本文标题:[奇技淫巧]使用ContentProvider初始化三方库

      本文链接:https://www.haomeiwen.com/subject/hxvzkctx.html