现在的位置: 首页 > 综合 > 正文

Android学习札记40:关于安全退出已创建多个Activity的应用(3)

2017年12月17日 ⁄ 综合 ⁄ 共 3083字 ⁄ 字号 评论关闭

在一个项目中,要退出 Android 程序,试了 restartPackage、 killBackgroundProcesses 、通过异常并在Application 的子类中重新注册 Thread 的 Thread.UncaughtExceptionHandler 接口+异常方式,等等,都没有效果。


最后发现其实只要在从一个 Activity A 跳到另一个 Activity B 时,调用了 A 的 finish 方法,程序就能退出,但这样不能实现 Back 操作了,最后想一个办法:我们为什么不自己控制程序创建的 Activity 呢?比如我们可以把程序创建的 Avtivity 放在一个全局变量里,在退出程序的时候取出每个还存在的 Activity,并对每个 Activity 依次调用
finish 最后程序就正常退出了。


先做以下几点说明:

(1)我们可以重写一个 Activity 管理类 ActivityManager,里面有一个堆栈结构,用来存放用户显示的 Activity,并暴露几个方法,一个向堆栈结构中加入 Activity,它主要用来当新建一个 Activity 时加入堆栈,另外一个从堆栈结构中取出一个 Activity,当用户调用 Back 按键时,要从堆栈中删除无用的 Activity,最后定义一个系统退出时清空
Activity 方法,并在清空 Activity 时调用每个 Activity 的 finish 方法完成内存资源的释放。


(2)为了共享复杂的数据类型,我们可以采用重写 Application 类的方法,在这个类里面定义一个成员---Activity 管理类 ActivityManager,这样它就可以被所有的 Activity 共享了。


(3)在适当的时候我们调用 ActivityManager 的入堆栈操作和出堆栈操作就行了。比如,在我的需求里,我在 onCreate 时调用入堆栈操作,在用户进行点击 Back 按键时进行出堆栈操作。


(4)为了减少代码的重复性,我们可以在实际操作时,自定义一个 Activity 基类,重写里面的 onCreate()方法和 onBackPressed 方法, onCreate 方法里我们把当前的 Activity 放入自定义 ActivityManager,onBackPressed 我们将当前 Activity 从 ActivityManager 中弹出。


先看ActivityManager类主要代码

import java.util.Stack;
public class ActivityManager {
	private static Stack<Activity> activityStack;
	private static ActivityManager instance;

	private ActivityManager() {
	}

	public static ActivityManager getScreenManager() {
		if (instance == null) {
			instance = new ActivityManager();
		}
		return instance;
	}

	// 退出栈顶Activity
	public void popActivity(Activity activity) {
		if (activity != null) {
			// 在从自定义集合中取出当前Activity时,也进行了Activity的关闭操作
			activity.finish();
			activityStack.remove(activity);
			activity = null;
		}
	}

	//获得当前栈顶Activity
	public Activity currentActivity() {
		Activity activity = null;
		if (!activityStack.empty())
			activity= activityStack.lastElement();
		return activity;
	}

	//将当前Activity推入栈中
	public void pushActivity(Activity activity) {
		if (activityStack == null) {
			activityStack = new Stack<Activity>();
		}
		activityStack.add(activity);
	}

	// 退出栈中所有Activity
	public void popAllActivityExceptOne(Class cls) {
		while (true) {
			Activity activity = currentActivity();
			
			if (activity == null) {
				break;
			}

			if (activity.getClass().equals(cls)) {
				break;
			}
			
			popActivity(activity);
		}
	}
}

再看看自定义的Application类

public class ApplicationEx extends Application {
	private static final String TAG = "ApplicationEx";

	private ActivityManager activityManager = null;

	public ApplicationEx() {
	}

	public ActivityManager getActivityManager() {
		return activityManager;
	}

	public void setActivityManager(ActivityManager activityManager) {
		this.activityManager = activityManager;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		// 初始化自定义Activity管理器
		activityManager = ActivityManager.getScreenManager();
	}
}

再看看我们自定义的一个Acitivity基类

public abstract class AbstractTemplateActivity extends Activity {

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		ApplicationEx application = (ApplicationEx) this.getApplication();
		application.getActivityManager().pushActivity(this);
	}

	@Override
	public void onBackPressed() {
		super.onBackPressed();
		ApplicationEx application = (ApplicationEx) getApplication();
		application.getActivityManager().popActivity(this);
	}
}

这样我们只要Activity都继承AbstractTemplateActivity,不需要在每个 Activity 中写 ApplicationEx application = (ApplicationEx) this.getApplication();application.getActivityManager().pushActivity(this); 等相关代码了。


在 Android 2.1 以上的版本都能实现 Activity 的完全退出。


转载自:

http://blog.csdn.net/sgl870927/article/details/6281971







抱歉!评论已关闭.