#android--自定义栈管理Activity,实现一次退出所有的Activity
来源:互联网 发布:软件可靠性指标 编辑:程序博客网 时间:2024/05/16 06:54
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,实现一次退出所有的Activity
- Android 一次退出所有activity的方法
- 实现activity管理器一次退出所有activity
- 实现activity管理器一次退出所有activity
- 一次退出所有的activity
- Activity管理—实现一次关闭所有的activity
- Android一次退出所有Activity的方法(升级版)
- Android退出所有的Activity
- Android 退出所有的Activity
- activity管理器一次退出所有activity
- android退出所有Activity
- android退出所有activity
- android退出所有activity
- android 退出所有Activity
- android退出activity时退出所有的activity
- android实现退出时关闭所有activity
- Android完全退出应用程序,Activity自定义管理栈
- 退出所有的Activity
- 使用VideoView进行视频播放
- 宏定义与typedef不能说的秘密
- Java多线程
- wallpaper Engine 安装教程
- centos7安装配置apache/httpd
- #android--自定义栈管理Activity,实现一次退出所有的Activity
- 学习Python csv模块遇到AttributeError: module 'csv' has no attribute 'writer'和写入后出现空格问题
- MFC 画线
- 一次曲折的下载经历
- Struts2-7 通用标签
- Word Break
- C语言文件操作
- [leetcode]406. Queue Reconstruction by Height
- 一个三流学校程序员的奋斗