#android--自定义栈管理Activity,实现一次退出所有的Activity
2017-01-06 21:59
429 查看
What–需求分析
今天写项目的时候遇到个问题,因为是加载的webview,点击响应时先会判断是否已经登录超时,如果是,那么结束掉之前的所有页面,回到登录页重新登录。那么问题就来了,之前只做过结束掉当前Activity,那么如何结束之前的所有栈中的Activity呢。看下面的分析How–如何去做
首先简单说一下堆栈的概念。如图所示,也就是先进后出的原则所以我们可以定义一个栈(Stack)去管理Activity,当创建Activity的时候就往栈添加这个Activity,当Activity销毁时就把这个Activity从这个栈里移除。想要finish掉所有Activity,只需要遍历stack,然后Finish掉每个Activity即可。
Code – 代码展示
首先来看一下管理Activity的关键类
因为用来管理Activity的类只能有一个实例,所以就用到了单例模式。在构造方法里创建了一个stack去管理Activity,Activity入栈是调用push方法,Activity出栈时调用pop方法。当结束掉所有Activity时遍历stack,然后finish。哦,记得一定要判空处理。
public class ActivityStackManager { private static ActivityStackManager mInstance; private static Stack<Activity> mActivityStack; public static ActivityStackManager getInstance() { if (null == mInstance) { mInstance = new ActivityStackManager(); } return mInstance; } private ActivityStackManager() { mActivityStack = new Stack<Activity>(); } // 入栈 public void addActivity(Activity activity) { mActivityStack.push(activity); Log.d("_addActivity","addActivity=="+activity.getLocalClassName()); } // 出栈 public void removeActivity(Activity activity) { mActivityStack.remove(activity); Log.d("removeActivity","removeActivity=="+activity.getLocalClassName()); } // 彻底退出 public void finishAllActivity() { Activity activity; while (!mActivityStack.empty()) { activity = mActivityStack.pop(); if (activity != null) { activity.finish(); Log.d("finishAllActivity","finishActivity=="+activity.getLocalClassName()); } } } // 结束指定类名的Activity public void finishActivity(Class<?> cls) { for (Activity activity : mActivityStack) { if (activity.getClass().equals(cls)) { finishActivity(activity); } } } // 查找栈中是否存在指定的activity public boolean checkActivity(Class<?> cls) { for (Activity activity : mActivityStack) { if (activity.getClass().equals(cls)) { return true; } } return false; } // 结束指定的Activity public void finishActivity(Activity activity) { if (activity != null) { mActivityStack.remove(activity); activity.finish(); activity = null; } } // finish指定的activity之上所有的activity public boolean finishToActivity(Class<? extends Activity> actCls, boolean isIncludeSelf) { List<Activity> buf = new ArrayList<Activity>(); int size = mActivityStack.size(); Activity activity = null; for (int i = size - 1; i >= 0; i--) { activity = mActivityStack.get(i); if (activity.getClass().isAssignableFrom(actCls)) { for (Activity a : buf) { a.finish(); } return true; } else if (i == size - 1 && isIncludeSelf) { buf.add(activity); } else if (i != size - 1) { buf.add(activity); } } return false; }
再来看一下如何在Activity中调用
因为相当于是一个全局的管理,所以把入栈出栈放在基类里面比较方便。看一下BaseAtivity里的代码public abstract class BaseActivity extends Activity{ @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityStackManager.getInstance().addActivity(this); } @Override protected void onDestroy() { ActivityStackManager.getInstance().removeActivity(this); super.onDestroy(); } }
ok,是不是很简单。在oncreate方法里把当前Activity压入栈中,然后在ondestory方法里将当前Activity从栈中弹出。
然后就是具体的 Activity去继承BaseActvity。好了,关键代码已完成。来看一个测试。点击MainActivity中的TextView 跳转到FirstActivity,点击FirstAtivity里的TextView跳转到SecondActivity……以此类推,当点击FourthActivity时结束掉所有的Activity并重新打开MainActivity。
具体代码:
MainActivity:
public class MainActivity extends BaseActivity { TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv= (TextView) findViewById(R.id.tv); tv.setText("MainActivity"); tv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v) { Log.d("_onclick","==MainActivity"); startActivity(new Intent(MainActivity.this,FirstActivity.class)); } }); } }
FourthActivity:
public class FourthActivity extends BaseActivity{ TextView tv; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv= (TextView) findViewById(R.id.tv); tv.setText("FourthActivity"); tv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v) { Log.d("_onclick","==FourthActivity"); startActivity(new Intent(FourthActivity.this,MainActivity.class)); ActivityStackManager.getInstance().finishAllActivity(); } }); }
对了,在管理Activity的那个类add和remove方法中输出log。
看一下输出日志:
可以看到,每次创建时就会往stack里添加Activity,当结束所有Activity时就会遍历stack,先走finish方法,触发ondestory方法,然后把Activity从Stack中移除。
这里有个疑问,就是看输出日志显示Finish掉Activity的顺序是Fourth、Third、Second、First 很符合逻辑,但是从stack中移除时的顺序是Third、Second、First、Fourth。按逻辑来说,finish的时候会走ondestory方法然后走remove方法的,所以不明白这里为什么Fourth是最后一个被移除的。希望有人指点迷津,不胜感激。
PS
ActivityStackManager 这个类原文找不到了,若有侵权,请指正。相关文章推荐
- Android一次退出所有Activity的方法(升级版)
- 退出Android程序时清除所有activity的实现方法
- Android应用实现退出时关闭所有Activity
- android中Activity实现再按一次退出
- Android 一次退出所有activity的方法
- Android中知道界面是哪个activity,一次结束所有Activity退出程序
- 实现activity管理器一次退出所有activity
- android实现退出时关闭所有activity
- 实现activity管理器一次退出所有activity
- 退出Android程序时清除所有activity的实现方法
- android中Activity实现再按一次退出
- 实现activity管理器一次退出所有activity
- Android 一次退出所有activity的方法
- Android一次退出所有Activity的方法(升级版)
- 【Android】【转】实现android中Activity实现再按一次退出
- Android实现退出时关闭所有Activity的方法
- android中实现完全退出程序方法(退出所有activity)
- Android中Activity实现再按一次退出
- Android中的“再按一次返回键退出程序”实现
- android退出activity提示再按一次返回键