使用 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 標簽,否則會造成沖突,此時這個類就顯得尤為必要了!