非侵入式获取Context进行SDK初始化
原创

非侵入试获取Context进行SDK初始化
当我们在使用第三方
SDK
,或者自己进行
SDK
封装时,如果需要需要用到
Context
进行初始化时,一般做法就是将初始化方法暴露给调用方,让调用方在初始化
SDK
时,传入上下文环境。
publi class App extends Application {
@Override
public void onCreate() {
super.onCreate();
MultiDex.install(getApplication());
if (Config.Debug)) {
ARouter.openLog();
ARouter.openDebug();
ARouter.init(this);
SkinSdk.init(this);
PaySDK.install(this);
/***部分代码省略***/
}
以上的
SDK
初始化代码是不是感觉很难维护。有没有一种直接拿来用而不需要进行
显式
初始化的SDK集成方式呢?
我们知道
ContentProvider
的生命周期,它是在
Application.attach
之后
Application.onCreate
之前进行
installProvider
。不需要我们
显式
通过代码启动。、
所以他满足了我们一般初始化 SDK 的条件:
-
拥有
Context[Application]
的上下文环境; - 可以进行自动启动;
如果大家平时注意观察会发现我们平时使用的一些
SDK
也是不需要显示初始化的,而他们都是使用自定义的
ContentProvider
这种方式。
picasso 初始化
相关知识可以阅读 Picasso源码分析和对比 这篇文章。
@RestrictTo(LIBRARY)
public final class PicassoProvider extends ContentProvider {
@SuppressLint("StaticFieldLeak") static Context context;
@Override public boolean onCreate() {
context = getContext();
return true;
/***部分代码省略***/
}
无侵入试的
Context
获取,依靠
ContentProvider
通过注册在
AndroidManifest.xml
实现自动启。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.squareup.picasso" >
<uses-sdk android:minSdkVersion="14" />
<application>
<provider
android:name="com.squareup.picasso.PicassoProvider"
android:authorities="${applicationId}.com.squareup.picasso"
android:exported="false" />
</application>
</manifest>
picasso
的初始化:
public class Picasso {
public static Picasso get() {
if (singleton == null) {
synchronized (Picasso.class) {
if (singleton == null) {
if (PicassoProvider.context == null) {
throw new IllegalStateException("context == null");
singleton = new Builder(PicassoProvider.context).build();
return singleton;
}
InstantRun
相关知识可以阅读 InstantRun从2.0到3.0,历史解毒 这篇文章。
<application android:theme="@style/AppTheme"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:name="com.example.tzx.changeskin.MyApplication"
android:debuggable="true"
android:testOnly="true"
android:allowBackup="true"
android:supportsRtl="true">
<activity android:name="com.example.tzx.changeskin.InstantRunActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<provider android:name="com.android.tools.ir.server.InstantRunContentProvider"
android:multiprocess="true" android:authorities="com.example.tzx.changeskin.com.android.tools.ir.server.InstantRunContentProvider"/>
</application>
InstantRunContentProvider
源码:
public final class InstantRunContentProvider extends ContentProvider {
public boolean onCreate() {
if (isMainProcess()) {
Log.i(Logging.LOG_TAG, "starting instant run server: is main process");
Server.create(getContext());
} else {
Log.i(Logging.LOG_TAG, "not starting instant run server: not main process");
return true;
private boolean isMainProcess() {
boolean isMainProcess = false;
if (AppInfo.applicationId == null) {
return false;
boolean foundPackage = false;
int pid = Process.myPid();
for (RunningAppProcessInfo processInfo : ((ActivityManager) getContext().getSystemService("activity")).getRunningAppProcesses()) {
if (AppInfo.applicationId.equals(processInfo.processName)) {
foundPackage = true;
if (processInfo.pid == pid) {
isMainProcess = true;
break;
if (isMainProcess || foundPackage) {
return isMainProcess;
Log.w(Logging.LOG_TAG, "considering this process main process:no process with this package found?!");
return true;
/***部分代码省略***/
}
Leakcanary
进行
LeakCanary
集成的
apk
文件中的
AndroidManifest.xml
会自动添加一下的配置:
<provider
android:name="leakcanary.internal.AppWatcherInstaller$MainProcess"
android:exported="false"
android:authorities="com.tzx.androidcode.leakcanary-installer" />
AppWatcherInstaller$MainProcess
源码:
internal sealed class AppWatcherInstaller : ContentProvider() {
* [MainProcess] automatically sets up the LeakCanary code that runs in the main app process.
internal class MainProcess : AppWatcherInstaller()
* When using the `leakcanary-android-process` artifact instead of `leakcanary-android`,
* [LeakCanaryProcess] automatically sets up the LeakCanary code
internal class LeakCanaryProcess : AppWatcherInstaller() {
override fun onCreate(): Boolean {
super.onCreate()
AppWatcher.config = AppWatcher.config.copy(enabled = false)
return true
override fun onCreate(): Boolean {