Android中多个ContentProvider的初始化顺序详解
作者:Sivan 发布时间:2021-11-06 03:52:36
缘起:
利用 ContentProvider 来初始化你的 Library, 这个相信大家已经不太陌生了,下面简要说下。
1. 利用 ContentProvider 初始化 Library:
在日常开发过程中, 经常会遇到 Library 都需要传入 Context 参数以完成初始化,此时这个 Context 参数一般会从 Application 对象的 onCreate 方法中获取。于是,很多 library 都会提供一个 init 方法,在Application Object中完成调用.
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Library.init(this);
}
}
至此, 相信大家可以看到依赖第三方 library 的时候,你必须得写一个自定义的 Application, 这样的用户体验可不太好。从 Android Debug Database, Firebase 中受到启发, 我们可以在 library 中创建一个 ContentProvider 来, 然后在 Manifest 中完成必要的注册信息, 在应用 Application 起来的时候会自动去初始化 library 中定义的 ContentProvider,现在就可以从 ContentProvider 中的 onCreate 里面得到 context 来初始化自己的 library。
public class FirstProvider extends ContentProvider {
@Override
public void attachInfo(Context context, ProviderInfo info) {
super.attachInfo(context, info);
}
@Override
public boolean onCreate() {
context = getContext();
// 这里可以初始化你需要的代码
return true;
}
......
}
```
这里顺便说一下Application, ContentProvider 初始化的顺序:
```java
Application.attachBaseContext(super before) -> Application.attachBaseContext(super after) -> ContentProvider.attachInfo(super before) -> ContentProvider.onCreate() -> ContentProvider.attachInfo(super after) -> Application.onCreate(super before) -> Application.onCreate(super after)
2. 自定义 ContentProvider 初始化顺序:
如果 library 中有业务需要用到多个自定义 ContentProvider,如 A、B、C, 但是自定义用来初始化的 provider 为D, 由于初始化流程在 provider D 中开始的, 那么 A、B、C 就必须在 D 之后起来才行,那么D ->A、B、C 顺序怎么来定义呢?也就是如何保证 D 最先初始化。
为了定义 provider 的初始化顺序,可以再 Manifest 中设置 initOrder 的值(值越大,最先初始化),同时如果 Library 中有多进程, 那么也需要设置 android:multiprocess,具体如下:
<provider
android:authorities="com.sivan.DContentProvider"
android:exported="false"
android:multiprocess="true"
android:initOrder="100"
android:name=".DContentProvider" />
如此在 Demo 中定义了 FirstProvider,SecondProvider 以及 ThirdProvider 的 initOrder 的值:
<provider
android:authorities="com.sivan.FirstProvider"
android:exported="false"
android:initOrder="100"
android:name=".FirstProvider" />
<provider
android:authorities="com.sivan.SecondProvider"
android:exported="false"
android:initOrder="50"
android:name=".SecondProvider" />
<provider
android:authorities="com.sivan.ThirdProvider"
android:exported="false"
android:name=".ThirdProvider" />
最后得到的日志信息如下:
MyApplication: attachBaseContext 0 pid = 3725
MyApplication: attachBaseContext 1 pid = 3725
FirstProvider: attachInfo 0 com.sivan.FirstProvider
FirstProvider: onCreate pid =3725
FirstProvider: attachInfo 1 com.sivan.FirstProvider
SecondProvider: attachInfo 0 info = com.sivan.SecondProvider
SecondProvider: onCreate pid = 3725
SecondProvider: attachInfo 1 info = com.sivan.SecondProvider
ThirdProvider: attachInfo 0 info = com.sivan.ThirdProvider
ThirdProvider: onCreate pid = 3725
ThirdProvider: attachInfo 1 info = com.sivan.ThirdProvider
MyApplication: onCreate 0 pid = 3725
MyApplication: onCreate 1 pid = 3725
可以看出初始化流程:FirstProvider -> SecondProvider -> ThirdProvider
所以我们需要根据 android:initOrder 来调整自定义用来初始化的 ContentProvider, 要保证 D 在 A、B、C 之前来初始化。
来源:https://sivanliu.github.io/2017/12/16/provider初始化/


猜你喜欢
- 一、动态编译简介new创建对象是静态加载类,在编译时刻就需要加载所有可能使用到的类。一百个类,有一个类错了,都无法编译。通过动态加载类可以解
- Result可以设定全局结果集,如:<struts> <constant name="struts
- 当我们的idea无法自动下在所需的Maven依赖时,我们可以到Maven的远程仓库中下载所需要的jar包,然后添加到我们的本地仓库中。1.首
- BufferedInputStream BufferedInputStream 是缓冲输入流。它继承于FilterInputSt
- 首先声明本文是基于GitHub上"baoyongzhang"的SwipeMenuListView修改而来,该项目地址:h
- 本文实例讲述了C#实现的文件操作封装类。分享给大家供大家参考,具体如下:最近发现群共享里面有个C# 文件操作封装类,其方法是调用Window
- C#.Net调用基本格式:DllImport 属性提供非托管 DLL 函数的调用信息。[DLLImport(“DLL文件
- 这篇文章主要介绍了Spring Batch批处理框架使用解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需
- 最近做了一个功能,里面涉及到了渐变圆形的需求。就是一个颜色可以渐变的圆环,最后实现的效果如下图:左图是带渐变效果,右图是不带渐变效果。原理还
- 对于一些特殊的情况,split拆分后并没有保留全的元素如下例子:String x ="a,,,,,,";String [
- 本文实例讲述了C#获取真实IP地址实现方法,分享给大家供大家参考。具体实现方法如下:通常来说,大家获取用户IP地址常用的方法是:string
- 1.创建项目修改依赖版本2.创建配置文件package com.huanmingjie.elasticsearch.config;impor
- 系统参数系统级全局变量,该参数在程序中任何位置都可以访问到。优先级最高,覆盖程序中同名配置。系统参数的标准格式为:-Dargname=arg
- 本文实例讲述了C#实现对象XML序列化的方法。分享给大家供大家参考。具体实现方法如下:using system;using system.x
- 定义:简单绑定是将一个用户界面元素(控件)的属性绑定到一个类型(对象)实例上的某个属性的方法。基本类型、包装类型、数组(以参数a
- 本文实例为大家分享了WPF自定义选择年月控件的具体代码,供大家参考,具体内容如下封装了一个选择年月的控件,XAML代码:<UserCo
- SpringMVC的数据响应SpringMVC的数据响应方式①页面跳转直接返回字符串(如在一个方法中,return了一个"xxx.
- 在安卓操作系统下对于 TextView 字体的支持非常有限,默认情况下 TextView 的 typeface 属性支持 "San
- 本文实例讲述了WinForm绘制圆角的方法。分享给大家供大家参考。具体实现方法如下:using System;using System.Co
- 命名空间using EnvDTE;using EnvDTE80;private DTE2 _applicationObject;