Android 退出应用程序和返回桌面

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按返回键退出程序但不销毁

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。