当我们在使用第三方库,或者自己封装库,如果需要需要用到Context时,一般做法就是将初始化方法暴露给调用方,让调用方在初始化类库时,传入Context。
publi class App extends Application {
/**
* 是否是Debug环境
*/
public static final boolean IS_DEBUG = true;
private static App mContext;
@Override
public void onCreate() {
super.onCreate();
//ARouter初始化
if (IS_DEBUG) {
ARouter.openLog();
ARouter.openDebug();
}
ARouter.init(this);
}
public static Context getInstance() {
return mContext;
}
}
2.解决方案
其实无侵入式获取Context的实现很简单,就是使用一个ContentProvider,ContentProvider的onCreate()方法调用时,调用getContext()即可获取到Context,再静态变量保存,后续直接获取即可。
上述的原理,其实是从Picasso中借鉴的,一起来看一下吧。
Picasso实例获取。重点在Double-Check单例中的PicassoProvider.context,调用PicassoProvider的context属性获取Context。
static volatile Picasso singleton = null;
public static Picasso get() {
if (singleton == null) {
synchronized (Picasso.class) {
if (singleton == null) {
//重点在这里,PicassoProvider.context获取Context
if (PicassoProvider.context == null) {
throw new IllegalStateException("context == null");
}
singleton = new Builder(PicassoProvider.context).build();
}
}
}
return singleton;
}
PicassoProvider类
PicassoProvider其实是一个ContentProvider的子类,只要将PicassoProvider在AndroidManifest清单文件中注册,启动App时,Android框架会初始化这个PicassoProvider,onCreate()方法被调用时,getContext()保存Context即可。
public final class PicassoProvider extends ContentProvider {
@SuppressLint("StaticFieldLeak") static Context context;
@Override public boolean onCreate() {
context = getContext();
return true;
}
}