1、结束进程
- KillProcess():
可以杀死当前应用活动的进程,这一操作将会把所有该进程内的资源(包括线程全部清理掉)。当然,由于ActivityManager时刻监听着进程,一旦发现进程被非正常Kill,它将会试图去重启这个进程。
android.os.Process.killProcess(android.os.Process.myPid());
- System.exit():
Java中结束进程的方法,调用它将关闭当前的JVM虚拟机。
//正常退出
System.exit(0);
//非正常退出
System.exit(1);
KillProcess() 和 System.exit(),许多人都使用过,当你栈里只有一个Activity的时候,这个措施是行之有效的。但当关闭多个Activity的时候,栈里有多个Activity时,这两个方法就不起作用了。
因为通过杀进程方式退出,会被系统认为异常退出,会保存应用的一些状态信息比如Activity运行栈,然后会恢复这个应用。当恢复一个Android应用程序时,会先从栈里面移除异常的Activity,相当于Back键操作。
2、容器式
自定义一个Actiivty栈,通过单例模式的Activity栈来管理所有Activity,创建一个Activity管理类来实现
public class AppManager {
private Stack<WeakReference<Activity>> mActivityStack;
private static volatile AppManager mInstance;
private AppManager() {
}
public static AppManager getInstance() {
if (mInstance == null) {
synchronized (AppManager.class) {
if (mInstance == null) {
mInstance = new AppManager();
}
}
}
return mInstance;
}
/**
* 添加Activity到堆栈
* @param activity activity实例
*/
public void addActivity(Activity activity) {
if (mActivityStack == null) {
mActivityStack = new Stack<>();
}
mActivityStack.add(new WeakReference<>(activity));
}
/**
* 检查弱引用是否释放,若释放,则从栈中清理掉该元素
*/
public void checkWeakReference() {
if (mActivityStack != null) {
for (Iterator<WeakReference<Activity>> it = mActivityStack.iterator(); it.hasNext(); ) {
WeakReference<Activity> activityReference = it.next();
Activity temp = activityReference.get();
if (temp == null) {
it.remove();// 使用迭代器来进行安全的加锁操作
}
}
}
}
/**
* 获取当前Activity
* @return 当前(栈顶)activity
*/
public Activity currentActivity() {
checkWeakReference();
if (mActivityStack != null && !mActivityStack.isEmpty()) {
return mActivityStack.lastElement().get();
}
return null;
}
/**
* 结束除当前activtiy以外的所有activity
* @param activtiy 不需要结束的activity
*/
public void finishOtherActivity(Activity activtiy) {
if (mActivityStack != null && activtiy != null) {
for (Iterator<WeakReference<Activity>> it = mActivityStack.iterator(); it.hasNext(); ) {
WeakReference<Activity> activityReference = it.next();
Activity temp = activityReference.get();
if (temp == null) {
// 清理掉已经释放的activity
it.remove();
continue;
}
if (temp != activtiy) {
// 使用迭代器来进行安全的加锁操作
it.remove();
temp.finish();
}
}
}
}
/**
* 结束除指定activtiy 集合以外的所有activity
* @param cls 指定的某类activity
*/
public void finishOtherActivity(Class<?> cls) {
if (mActivityStack != null) {
for (Iterator<WeakReference<Activity>> it = mActivityStack.iterator(); it.hasNext(); ) {
WeakReference<Activity> activityReference = it.next();
Activity activity = activityReference.get();
if (activity == null) {
// 清理掉已经释放的activity
it.remove();
continue;
}
if (!activity.getClass().equals(cls)) {
// 使用迭代器来进行安全的加锁操作
it.remove();
activity.finish();
}
}
}
}
/**
* 结束当前Activity
*/
public void finishActivity() {
Activity activity = currentActivity();
if (activity != null) {
finishActivity(activity);
}
}
/**
* 结束指定的Activity
* @param activity 指定的activity实例
*/
public void finishActivity(Activity activity) {
if (activity != null) {
for (Iterator<WeakReference<Activity>> it = mActivityStack.iterator(); it.hasNext(); ) {
WeakReference<Activity> activityReference = it.next();
Activity temp = activityReference.get();
if (temp == null) {
// 清理掉已经释放的activity
it.remove();
continue;
}
if (temp == activity) {
it.remove();
}
}
activity.finish();
}
}
/**
* 结束指定类名的所有Activity
* @param cls 指定的类的class
*/
public void finishActivity(Class<?> cls) {
if (mActivityStack != null) {
for (Iterator<WeakReference<Activity>> it = mActivityStack.iterator(); it.hasNext(); ) {
WeakReference<Activity> activityReference = it.next();
Activity activity = activityReference.get();
if (activity == null) {
// 清理掉已经释放的activity
it.remove();
continue;
}
if (activity.getClass().equals(cls)) {
it.remove();
activity.finish();
}
}
}
}
/**
* 结束所有Activity
*/
public void finishAllActivity() {
if (mActivityStack != null) {
for (Iterator<WeakReference<Activity>> it = mActivityStack.iterator(); it.hasNext(); ) {
WeakReference<Activity> activityReference = it.next();
Activity activity = activityReference.get();
if (activity != null) {
activity.finish();
}
}
mActivityStack.clear();
}
}
/**
* 退出应用程序
*/
public void exitApp() {
try {
finishAllActivity();
// 从操作系统中结束掉当前程序的进程
android.os.Process.killProcess(android.os.Process.myPid());
} catch (Exception e) {
Log.e("Exit exception", e.getMessage());
}
}
}
使用方式:
- 在BaseActivity#onCreate回调中添加AppManager.getInstance().addActivity(this)
- 获取当前栈顶activityAppManager.getInstance().currentActivity()
- 销毁当前activity:调用AppManager.getInstance().finishActivity()->可在BaseActivity#onDestroy添加
- 销毁指定activity:调用AppManager.getInstance().finishActivity(XXX.class)
- 销毁指定activity集合:调用AppManager.getInstance().finishActivity(Class<Activity> cls)
- 结束除当前activtiy以外的所有activity:调用AppManager.getInstance().finishOtherActivity(XXX.class)
- 结束除当前activtiy集合以外的所有activity:调用AppManager.getInstance().finishOtherActivity(Class<Activity> cls)
- 结束所有activity:调用finishAllActivity()
- 退出应用调用AppManager.getInstance().exitApp()
在BaseActivity基类中添加引用,把所有Activity存储起来,Activity销毁的时候移除栈
public class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 添加Activity到堆栈
AppManager.getInstance().addActivity(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
//移除当前Activity
AppManager.getInstance().finishActivity(this);
}
}
如果activityStack持有Activity的强引用,当某个Activity异常退出时,activityStack没有及时释放掉引用,可能会导致内存问题。
退回系统桌面,不退出应用
Android应用开发中,有一种场景,就是我们不希望用户直接按Back键退出Activity,而是希望应用隐藏到后台的假退出,类似于按Home键的效果。
方法一:
public void onBackHome(Activity activity) {
if (activity != null) {
Intent home = new Intent(Intent.ACTION_MAIN);
home.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
home.addCategory(Intent.CATEGORY_HOME);
activity.startActivity(home);
}
}
方法二:
public void onBackgroud(Activity activity, boolean isTaskRoot) {
if (activity != null) {
activity.moveTaskToBack(false);
}
}
moveTaskToBack()方法:在activity中调用 moveTaskToBack (boolean nonRoot)方法即可将activity 退到后台,不是finish()退出activity。
参数说明:
参数为false——代表只有当前activity是task根,指应用启动的第一个activity时,才有效;
参数为true——则忽略这个限制,任何activity都可以有效。
说明:判断Activity是否是task根,Activity本身给出了相关方法:isTaskRoot()
moveTaskToBack调用后,task中activity的顺序不会发生变化,例如A启动B,B中调用此方法退到后台,重新启动应用会调用B中的onRestart-onStart-onResume方法,不会重新调用onCreate,而且在B中按下back键返回的还是A,这就是退到后台的功能。类似于系统home键效果。
参考:
一招搞定Android Activity的管理
android常见技巧---Android按返回键退出程序但不销毁
网友评论