使用 Context 的场景就不必多说了,Toast 啊、广播啊、通知啊等等等等,当然一般来说我们都是通过配置 Application 来获取全局的上下文实例,这也是应有之义,这里也写一下好了:
public class AppContext extends Application { private static Context instance; @Override public void onCreate() { super.onCreate(); instance = getApplicationContext(); } public static Context getContext() { return instance; } }
然后在 Manifest 中 application 标签下添加 name 属性
android:name="xxx.xxx.xxx.AppContext"
一般而言就是上述这样了,接下来要说的是碰到一些特殊情况无法配置 Application,这时要获取全局 Context 该如何呢。
先上代码:
public class Applications { @NonNull public static Application context() { return CURRENT; } @SuppressLint("StaticFieldLeak") private static final Application CURRENT; static { try { Object activityThread = getActivityThread(); Object app = activityThread.getClass().getMethod("getApplication") .invoke(activityThread); CURRENT = (Application) app; } catch (Throwable e) { throw new IllegalStateException("Can not access Application context by magic code, boom!", e); } } private static Object getActivityThread() { Object activityThread = null; try { @SuppressLint("PrivateApi") Method method = Class.forName("android.app.ActivityThread") .getMethod("currentActivityThread"); method.setAccessible(true); activityThread = method.invoke(null); } catch (final Exception e) { Log.w(TAG, e); } return activityThread; } }
看起来很简单对不对,其实其中复杂程度很高,具体内容可以看一种Android应用内全局获取Context实例的装置这篇博文。
真看下去可以说收获颇多,如果只是使用的话直接取上面的 Applications 类即可,无需经过任何初始化即可在全局获取 Context 实例,当然有可能会与一些 HotFix 框架冲突,具体情况可在应用中自行查看。
至于我碰到的特殊情况,对,就是上篇文章中讲到的特麻烦结果最后才发现没必要的东西,因为要将项目 A 集成到项目 B中的话,A 的 Manifest 中必然不能配置 application 标签,否则会造成冲突,此时这个类就显得尤为必要了!