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