最近項(xiàng)目中遇到一個(gè)問題斤寂,需要做一個(gè)全局的彈窗丘侠,為此需要拿到當(dāng)前棧頂?shù)?Activity。在這里做一個(gè)總結(jié):
- ActivityManager.getRunningTasks()
這個(gè)函數(shù)是官方的 public API句狼,但已經(jīng)廢棄粱快,原因是:“可能造成隱私泄露”。但因?yàn)榧嫒菪栽蜓匮匀粫?huì)返回一小部分不敏感的數(shù)據(jù)览徒,比如當(dāng)前進(jìn)程的 Activities 或者 Launcher。
換句話說颂龙,在 Android L 以上习蓬,返回結(jié)果非常不可靠,而且只能拿到ComponentName 而不是 Activity 實(shí)例措嵌,不建議使用躲叼。
public static ComponentName getTopActivity(Context c) {
ActivityManager am = (ActivityManager) c
.getSystemService(Context.ACTIVITY_SERVICE);
if (am != null) {
List<ActivityManager.RunningTaskInfo> infos
= am.getRunningTasks(1);
if (infos != null && infos.size() != 0) {
return infos.get(0).topActivity;
}
}
return null;
}
- BaseActivity 記錄生命周期回調(diào)
這個(gè)方法對(duì)于沒有繼承 BaseActivity 的 Activity 是無效的……由此可見在項(xiàng)目開始時(shí)創(chuàng)建基類成員并寫進(jìn)開發(fā)規(guī)范多么重要……
public abstract class BaseActivity extends AppCompatActivity {
private static WeakReference<BaseActivity> sTopActivity;
public static BaseActivity getTopActivity() {
return sTopActivity == null ? null : sTopActivity.get();
}
@Override
protected void onStart() {
super.onStart();
sTopActivity = new WeakReference<>(this);
}
@Override
protected void onStop() {
super.onStop();
if (getTopActivity() == this) {
sTopActivity = null;
}
}
}
- Application.registerActivityLifecycleCallback
這個(gè)方法可以在 Application 的 onCreate 函數(shù)中注冊(cè)
private static WeakReference<Activity> sTopActivity;
public static Activity getTopActivity() {
return sTopActivity == null ? null : sTopActivity.get();
}
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(Activity activity) {
sTopActivity = new WeakReference<>(activity);
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
if (activity == getTopActivity()) {
sTopActivity = null;
}
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
});
}
- ActivityThread.ActivityClientRecord
這個(gè)方法是實(shí)際我使用的,因?yàn)轫?xiàng)目是 Xposed 模塊企巢,可能是本機(jī)代碼優(yōu)化的原因枫慷,Application.onCreate() 函數(shù) hook 不到,就算 hook 到了注冊(cè)成功也收不到回調(diào)浪规,有點(diǎn)莫名其妙或听。如果看過 ActivityThread 的源碼,會(huì)發(fā)現(xiàn)里面有一個(gè)內(nèi)部類 ActivityClientRecord笋婿,這個(gè)類是用來保存本進(jìn)程所有 Activity 實(shí)例及生命狀態(tài)的誉裆。缺點(diǎn)是:由于使用了反射和內(nèi)部類,兼容性無法保證缸濒,如果 ROM 廠商改個(gè)名字可能就跪了足丢。而且 Android 9 以上限制了反射的使用,需要進(jìn)行一下適配庇配。
private boolean mIgnore = false;
private Field mActivityField;
private Field mActivitiesField;
private Field mStoppedField;
@SuppressWarnings("unchecked")
private Activity getTopActivity() {
if (mIgnore) {
return null;
}
try {
if (mActivitiesField == null) {
mActivitiesField = ReflectUtils.getDeclaredField(
ActivityThread.class, "mActivities"
);
Class<?> cls = Class.forName("android.app.ActivityThread$ActivityClientRecord");
mActivityField = ReflectUtils.getDeclaredField(cls, "activity");
mStoppedField = ReflectUtils.getDeclaredField(cls, "stopped");
}
ActivityThread thread = ActivityThread.currentActivityThread();
final Map<Object, Object> mActivities = (Map<Object, Object>)
mActivitiesField.get(thread);
for (Object r : mActivities.values()) {
Activity activity = (Activity) mActivityField.get(r);
if (activity.isFinishing() || activity.isDestroyed()
|| ((boolean) mStoppedField.get(r))) {
continue;
}
return activity;
}
} catch (Exception e) {
mIgnore = true;
Log.e(TAG, "getTopActivity: ", e);
}
return null;
}
下面是 ReflectUtils
public static Field getDeclaredField(Class<?> cls, String name) {
Field field;
try {
field = cls.getDeclaredField(name);
field.setAccessible(true);
} catch (NoSuchFieldException e) {
field = null;
Log.e(TAG, "getDeclaredField: " + name, e);
}
return field;
}
對(duì)于 Android9 以上斩跌,可以參考
http://weishu.me/2019/03/16/another-free-reflection-above-android-p/