如何安全退出已调用多个 Activity 的 Application?

如何安全退出已调用多个 Activity 的 Application?

  • 记录打开的Activity
    • 每打开一个Activity,就记录下来,在需要退出时,关闭每一个activity。
  • 发送特定的广播
    • 在需要结束应用时,发送一个特定的广播,每一个Activity收到广播后关闭。
  • 通过 intent 的 flag 来实现
    • 实现intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) 激活
      一个新的 activity。此时如果该任务栈中已经有该 Activity,那么系统会把这个 Activity 上面的所有 Activity 干掉。其实相当于给 Activity 配置的启动模式为 SingleTop。

这里我们就来看看第一种方法是如何实现的

1.创建一个类(MyApplication)继承Application

public class MyApplication extends Application{

2.创建一个用于存放activity的集合,这里可以创建一个Activity的基类,叫BaseActivty,让所有的Activity都继承它,在BaseActivity中我们可以写共性的方法或变量等。

//创建一个用于存放Activitiy的集合
 List mActivityList = new ArrayList<>();

3.添加3个方法,分别用于添加Activity,移除Activity,清空集合

  //提供一个添加activity的方法
    public void addActivity(BaseActivity activity) {
        if (!mActivityList.contains(activity)) {
            mActivityList.add(activity);
        }
    }

    //提供一个移除activity的方法
    public void removeActivity(BaseActivity activity) {
        if (!mActivityList.contains(activity)) {
            mActivityList.remove(activity);
        }
    }

    //提供一个清空集合的方法
    public void clearAllActivity() {
        for (int i = 0; i< mActivityList.size(); i++) {
            BaseActivity activity = mActivityList.get(i);
            activity.finish();
        }
        mActivityList.clear();
    }

到此,我们的MyApplication就实现了以上的功能,接下来只需要在BaseActivity中调用就可以了。


1.首先在onCreate方法中,获取到MyApplication的对象,并调用addActivity()方法。

public class BaseActivity extends AppCompatActivity{
    private MyApplication mApplication;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mApplication = (MyApplication) getApplication();
        mApplication.addActivity(this);    //一旦创建了一个Activity,那么就加入到集合中
    }

2.其次,在BaseActivity的onDestroy()方法中,我们将该Activity移除

 @Override
    protected void onDestroy() {
        super.onDestroy();
        mApplication.removeActivity(this);//移除Activity
    }

写到这里,我们发现clearAllActivity()这个方法,该怎么被调用呢,如果我们退出了一个应用,那么自然的Activity都被销毁了,并且在实际开发中,按返回键,最后都会回到主界面的Activity中,然后,再连按两下,应用就退出了,这个在我们生活中很常见。

那么这个是怎么实现的呢?

其实就是在Activity的onBackPressed()方法中,计算出两次点击的时间差,如果在2秒内点击2次,就退出,否则就弹出Toast提示。

private long mStartTime;    //定义一个成员变量,默认初始时间为0
    @Override
    public void onBackPressed() {
        super.onBackPressed();
        //当点击的时候计算2次点击的时间差,如果在2秒之内点击2次,就退出
        long currentTimeMillis = System.currentTimeMillis();
        if ((currentTimeMillis - mStartTime) < 2000) {
            this.finish();
        } else {
            Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
            mStartTime = System.currentTimeMillis();    //记录点击后的时间
        }
    }

好,我们回过来,在实际应用中,安全退出已调用多个Activity的Application,在某个应用场景下非常常见,那就是当你的账号在其他设备上登录了,那你这边的账号就会断开,并且重新跳转到登录界面,这个时候我们就要清空我们所有的任务栈。

在利用环信的sdk进行社交类应用的开发时,看到环信提供了一个监听的回调方法,我们可以重写其中的onDisconnected(int i),代码如下:

EMClient.getInstance().addConnectionListener(new EMConnectionListener() {
            @Override
            public void onConnected() {
            }
            @Override
            public void onDisconnected(int i) {
                final Intent intent = new Intent(getApplicationContext(),LoginActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//在非activity中,要唤起一个activity,就要重现创建一个任务栈
                //客户端和服务器断开连接了
                if(i == EMError.USER_REMOVED){
                    // 显示帐号已经被移除
                    //跳转到登录界面
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            ToastUtil.showToast(getApplicationContext(),"您已被后台删除,请重新登录或注册!");
                            //清空所有任务栈
                            clearAllActivity();
                            startActivity(intent);
                        }
                    });
                }else if (i == EMError.USER_LOGIN_ANOTHER_DEVICE) {
                    // 显示帐号在其他设备登录
                    //跳转到登录界面
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            ToastUtil.showToast(getApplicationContext(),"您的账号已经在另外一台设备登录,请重新登录!");
                            //清空所有任务栈
                            clearAllActivity();
                            startActivity(intent);
                        }
                    });
                }

第一次用markdown写,格式丑请见谅。
欢迎指正错误。

你可能感兴趣的:(android)