【Android Tip】
Android 獲取當(dāng)前Activity對象的方式:
背景:(當(dāng)你不能使用this獲取Activity對象)如何方便地當(dāng)前Activity對象
思路:
1.維護(hù)對象棧
維護(hù)一個(gè)Activity的対象棧,在每個(gè)Activity的生命周期方法執(zhí)行的時(shí)候,控制add和remove奉狈,棧頂元素就是當(dāng)前的Activity對象。為了代碼的復(fù)用硅卢,這個(gè)操作可以寫在BaseActivity中射窒,這個(gè)思路很正常。代碼就不貼了将塑。
2. 反射
使用反射來獲取當(dāng)前Activity對象脉顿。(個(gè)人認(rèn)為是相對優(yōu)雅和解耦的方式)
查看源碼發(fā)現(xiàn) Activity Thread 這個(gè)類管理著所有的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è)計(jì)并不是用來做當(dāng)前的操作,所以源碼修改可能導(dǎo)致該方法不能用敢辩,而且蔽莱,評論區(qū)也出現(xiàn)了拿不到activitys的情況,說明該方法穩(wěn)定性也不是最佳戚长。
3. (推薦)Framework回調(diào)
Android自 API 14開始引入了一個(gè)方法盗冷,即Applicationd的registerActivityLifecycleCallbacks方法,用來監(jiān)聽所有Activity的生命周期回調(diào)同廉,比如onActivityCreated,onActivityResumed等仪糖。
So,一個(gè)簡單的實(shí)現(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