有一个需求,就是走完一个流程,需要通过A,B,C,D,E,F六个Activity,然后在最后提交以后,要返回到A,关闭B,C,D,E,F,要实现这个功能,简单粗暴的方法,就是在类中,定义一个staitic变量,比如 public static A instance;,在oncreate方法中设置instance = this;,在onDestroy方法中设置instance = null;然后在提交以后,判断
if (A.instance != null)
{
A.instance.finish();
}
,以此类推,B,C,D,E,F,都设置,这个方法的弊端就是,类太多的话,管理不容易,需要一个一个赋值,容易遗漏,另外一种方法,就是设置一个Activity的列表,将需要关闭的类add进去,然后遍历关闭,代码虽然一样,也是可能遗漏,实现这种功能的方法有很多,参考Android中一个Activity关闭另一个Activity或者在一个Activity中关闭多个Activity,我现在用的一个方法:
原理是,获取到栈中所有activity,然后设置需要返回的AActivity: intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
,因为FLAG_ACTIVITY_CLEAR_TOP ,所以AActivity启动时,同一任务栈中位于它上边的Activity会出栈,所以B,C,D,E,F从堆栈中会弹出
首先要获取这个流程的栈,
private static List<Activity> getActivitiesByApplication(Application application) {
List<Activity> list = new ArrayList<>();
try {
Class<Application> applicationClass = Application.class;
Field mLoadedApkField = applicationClass.getDeclaredField("mLoadedApk");
mLoadedApkField.setAccessible(true);
Object mLoadedApk = mLoadedApkField.get(application);
Class<?> mLoadedApkClass = mLoadedApk.getClass();
Field mActivityThreadField = mLoadedApkClass.getDeclaredField("mActivityThread");
mActivityThreadField.setAccessible(true);
Object mActivityThread = mActivityThreadField.get(mLoadedApk);
Class<?> mActivityThreadClass = mActivityThread.getClass();
Field mActivitiesField = mActivityThreadClass.getDeclaredField("mActivities");
mActivitiesField.setAccessible(true);
Object mActivities = mActivitiesField.get(mActivityThread);
// 注意这里一定写成Map,低版本这里用的是HashMap,高版本用的是ArrayMap
if (mActivities instanceof Map) {
@SuppressWarnings("unchecked")
Map<Object, Object> arrayMap = (Map<Object, Object>) mActivities;
for (Map.Entry<Object, Object> entry : arrayMap.entrySet()) {
Object value = entry.getValue();
Class<?> activityClientRecordClass = value.getClass();
Field activityField = activityClientRecordClass.getDeclaredField("activity");
activityField.setAccessible(true);
Object o = activityField.get(value);
list.add((Activity) o);
Log.e("getClassName",((Activity) o).getComponentName().getClassName());
}
}
} catch (Exception e) {
e.printStackTrace();
list = null;
}
return list;
}
使用:
private List<Activity> activities=new ArrayList<>();
activities=getActivitiesByApplication(MyApplication.newInstance());
if(activities!=null){
for(Activity activity:activities){
if(activity.getComponentName().getClassName().contains("AActivity")){
((AActivity)activity).startActivity(FActivity.this);
finish();
}
}
}
设置AActivity的launchMode为singleTop,
<activity android:name="xxxx.AActivity"
android:launchMode="singleTop">
public static void startActivity(Context context)
{
Intent intent = new Intent(context, AActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intent);
}
@Override
protected void onNewIntent(Intent intent)
{
setIntent(intent);
}
lanchMode为singleTop,如果已经位于栈顶,不会重新创建,会调用onNewIntent()