借鉴自http://blog.csdn.net/guolin_blog/article/details/47028975
Context数量 = Activity数量 + Service数量 + 1
ContextWrapper源码
public class ContextWrapper extends Context { Context mBase; public ContextWrapper(Context base) { mBase = base; } /** * Set the base context for this ContextWrapper. All calls will then be * delegated to the base context. Throws * IllegalStateException if a base context has already been set. * * @param base The new base context for this wrapper. */ protected void attachBaseContext(Context base) {//添加ContextImpl的方法 if (mBase != null) { throw new IllegalStateException("Base context already set"); } mBase = base; } /** * @return the base context as set by the constructor or setBaseContext */ public Context getBaseContext() {//取得ContextImpl的方法 return mBase; } @Override public AssetManager getAssets() { return mBase.getAssets(); } @Override public Resources getResources() { return mBase.getResources(); } @Override public PackageManager getPackageManager() { return mBase.getPackageManager(); } @Override public ContentResolver getContentResolver() { return mBase.getContentResolver(); } @Override public Looper getMainLooper() { return mBase.getMainLooper(); }为什么我们Activity中直接可以一个方法名就搞定的东西,在其他地方需要context.方法名呢,因为Activity就是Context的子类。再看看源码,是通过一种类似代理的方式,进行调用,调用的是ContextImpl里的方法。(这是源码里常用的方式,通过多态性,传一个接口或者父类,把其他类里方法迁移到自己这个类里来。)
所以最快速度初始化的方法
@Override protected void attachBaseContext(Context base) { // 在这里调用Context的方法会崩溃 super.attachBaseContext(base); // 在这里可以极致速度调用Context的方法 }
正确获得Application的姿势
public class MyApplication extends Application { private static MyApplication app; public static MyApplication getInstance() { return app; } @Override public void onCreate() { super.onCreate(); app = this; } }
不仅如此,Application中不应该作为一个工具类,而比较适合作为全局静态实例(而且是非声明不可的那种,和app同生命周期的变量,如user)的提供者。