美文网首页Android开发Android进阶之路Android开发
Android 退出应用程序和返回桌面

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

作者: 听话哥 | 来源:发表于2018-12-25 17:09 被阅读4次

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

    相关文章

      网友评论

        本文标题:Android 退出应用程序和返回桌面

        本文链接:https://www.haomeiwen.com/subject/opmflqtx.html