【Android Tip】
Android 獲取當(dāng)前Activity對象的方式:
背景:(當(dāng)你不能使用this獲取Activity對象)如何方便地當(dāng)前Activity對象
思路:
1.維護對象棧
維護一個Activity的対象棧,在每個Activity的生命周期方法執(zhí)行的時候,控制add和remove,棧頂元素就是當(dāng)前的Activity對象。為了代碼的復(fù)用,這個操作可以寫在BaseActivity中,這個思路很正常。代碼就不貼了。
2. 反射
使用反射來獲取當(dāng)前Activity對象。(個人認為是相對優(yōu)雅和解耦的方式)
查看源碼發(fā)現(xiàn) Activity Thread 這個類管理著所有的Activity對象,也就持有所有的Activity對象,使用反射獲得當(dāng)前ActivityThread對象
,然后就能拿到當(dāng)前的Activity對象
示例:
public static Activity getCurrentActivity () {
try {
Class activityThreadClass = Class.forName("android.app.ActivityThread");
Object activityThread = activityThreadClass.getMethod("currentActivityThread").invoke(
null);
Field activitiesField = activityThreadClass.getDeclaredField("mActivities");
activitiesField.setAccessible(true);
Map activities = (Map) activitiesField.get(activityThread);
for (Object activityRecord : activities.values()) {
Class activityRecordClass = activityRecord.getClass();
Field pausedField = activityRecordClass.getDeclaredField("paused");
pausedField.setAccessible(true);
if (!pausedField.getBoolean(activityRecord)) {
Field activityField = activityRecordClass.getDeclaredField("activity");
activityField.setAccessible(true);
Activity activity = (Activity) activityField.get(activityRecord);
return activity;
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
由于源碼的設(shè)計并不是用來做當(dāng)前的操作,所以源碼修改可能導(dǎo)致該方法不能用,而且,評論區(qū)也出現(xiàn)了拿不到activitys的情況,說明該方法穩(wěn)定性也不是最佳。
3. (推薦)Framework回調(diào)
Android自 API 14開始引入了一個方法,即Applicationd的registerActivityLifecycleCallbacks方法,用來監(jiān)聽所有Activity的生命周期回調(diào),比如onActivityCreated,onActivityResumed等。
So,一個簡單的實現(xiàn)如下:
public class BaseApplication extends Application {
//為避免內(nèi)存泄漏使用弱引用
private WeakReference<Activity> mCurrentActivity;
@Override
public void onCreate () {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated (Activity activity, Bundle bundle) {
//do nothing
}
@Override
public void onActivityStarted (Activity activity) {
//do nothing
}
@Override
public void onActivityResumed (Activity activity) {
mCurrentActivity = new WeakReference<>(activity);
}
@Override
public void onActivityPaused (Activity activity) {
//do nothing
}
@Override
public void onActivityStopped (Activity activity) {
//do nothing
}
@Override
public void onActivitySaveInstanceState (Activity activity, Bundle bundle) {
//do nothing
}
@Override
public void onActivityDestroyed (Activity activity) {
//do nothing
}
});
}
}
}
思路來自:stackoverflow