您的位置:首页 > 移动开发 > Android开发

#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 这个类原文找不到了,若有侵权,请指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: