Android Tips--退出应用程序

Android退出应用程序的方法有好几种,比较常用的有创建一个管理各个Activity的类,或者设置activity的启动模式等等,这里对这些常见的方法作以介绍。

自定义Activity管理类

这种方法应该是很常见的,就是我们自定义一个类,类里面实现管理Activity的几种方法。
这里首先是建立一个ActivityManager类,以一个activityList来存放我们生成的Activity,并在类里定义添加Activity(addActivity())、移除Activity(removeActivity())、以及结束所有Activity的方法。

import java.util.ArrayList;
import java.util.List;

public class ActivityManager {
    private static List<Activity> activityList=new ArrayList<>();
    public static void addActivity(Activity activity){
        activityList.add(activity);
    }
    public static void removeActivity(Activity activity){
        activityList.remove(activity);
    }
    public static void finishAllActivities(){
        for(Activity activity:activityList){
            activity.finish();
            removeActivity(activity);
        }
    }

}

然后我们建立一个基础Activity,即BaseActivity,并重写这个Activity的onCreate方法和onDestroy方法如下:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class BaseActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityManager.addActivity(this);//将Activity加入List
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityManager.removeActivity(this);//销毁Activity时从List中移除该Activity
    }
}

有了这两个工具,此后我们在新建Activity时只需让新的Activity继承BaseActivity而不是Activity即可,这样就会将我们生成的Activity自动加入activityList中,而每一个Activity在销毁时也会自动从activityList中移除。
在需要退出整个应用时只需要调用ActivityManager的静态方法finishAllActivities()即可


上面这种方法实现起来相当简单,也非常容易明白,但是并不是一种令人满意的方式,为什么呢?在说原因之前我们先来熟悉一个概念—强引用
强引用是指创建一个对象,并将这个对象赋给一个引用变量,而强引用在有引用变量指向时是不会被Java垃圾回收的,即使是内存不足,回收也不会发生。
可以看出,我们上面的activityList就拥有着对那些Activities的强引用,也就是说某Activity异常退出时,activityList没有及时地释放掉对其的引用,导致内存无法回收,这就很尴尬了,所以我们需要更为友好的退出方式。

使用广播

同样是使用上面的BaseActivity的方式,但这次我们可以在BaseActivity里注册一个广播,当我们需要退出程序时发送一个广播,然后finish退出即可。
当然我们需要先建一个广播接收器以完成接到广播后所应执行的退出操作:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class BaseActivity extends AppCompatActivity {
    private ExitBroadcastReceiver exitBroadcastReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        IntentFilter filter=new IntentFilter("com.example.myskety.exit");//设置广播过滤器
        exitBroadcastReceiver=new ExitBroadcastReceiver();//实例化
        registerReceiver(exitBroadcastReceiver,filter);//注册广播接收器

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(exitBroadcastReceiver);

    }
    class ExitBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            BaseActivity.this.finish();
        }
    }
}

下面说一下上述代码的工作流程:
我们在BaseActivity里注册了一个广播接收器,并且为这个广播接收器设置了广播过滤:intentfilter,用来只是接收退出应用的广播,最后在BaseActivity的onDestroy方法里注销了广播接收器,这样,每个继承自BaseActivity的Activity都拥有了销毁自己的能力,因为它们都能接收到退出应用的广播,然后finish,而我们只需在要进行结束应用的地方把命令广播出去即可,如下:

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class Main2Activity extends BaseActivity {
    private TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        tv=(TextView)findViewById(R.id.tv);
        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              Intent intent=new Intent("com.example.myskety.exit");
                sendBroadcast(intent);
            }
        });
    }
}

相信大家一定都接触另一种退出应用的方式—-连续两次back键退出应用,这一方式又是怎么实现的呢?在了解这一方式之前我们先来看一下Activity的四种加载模式singleTask
首先我们来了解一下Activity的四种启动模式:
一、standard:standard是活动默认的启动模式,未进行显示指定时,所有活动都会自动使用这种启动模式,这种模式下,每启动一个新的Activity,它就会在返回栈中入栈,且位于栈顶,这种activity,系统不在乎其是否已经在返回栈中存在,每次启动Activity都会在栈顶创建一个该Activity的实例。
二、singleTop:显然,standard模式会让人觉得有些不合理:活动明明已经在栈顶,却在再次启动时创建新的活动实例。因此系统允许我们自行修改启动模式,singleTop模式意思是当启动活动时若发现返回栈栈顶已经是待启动的活动,则认为可以直接使用该实例,不会再创建新的实例。设置singleTop模式是在AndroidManifest.xml中< activity >标签 中:android:launchMode=”singleTop”,另外两种模式设置也是一样。
三、singleTask:若待启动的活动不在栈顶怎么办呢?岂不是还要再次创建新的实例?这时就需要singleTask了,这种模式下,每当启动活动时系统会在返回栈中检查是否已经存在对应实例,若存在则直接使用,并将它上面的所有活动全部出栈,如果没有,则会新建实例。
四、singleInstance:与上三种模式不同,这种模式下的活动会启动一个新的返回栈来管理该活动,这是为了解决其他程序和我们的程序共享该活动的实例的问题。上三种模式 下,同一个活动在不同程序的不同返回栈里必然会创建新的实例,显然无法满足需要,这才有了singleInstance模式,将该活动用一个单独的返回栈管理,这样多个应用程序公用一个管理该活动的返回栈,就可以共享活动了。
好了,下面我们介绍一种应用Receiver+singleTask的退出方式:
我们的应用在启动后都是在主页的基础上做若干次跳转,期间的activity或被销毁,或在栈中,但我们的HostActivity始终位于栈底!所以我们要做的很简单,只需要两步:
一:在HostActivity注册一个退出广播,留作销毁它自身
二:设置HostActivity启动模式为singleTask
这样一来,我们在退出时也是只需要做两步:
一:startActivity(this,HostActivity),这样,栈底上面的所有活动都会出栈。
二:发送退出广播(仅仅针对HostActivity)


这里,继续我们刚才的连续back退出应用的处理方式,有了上面的基础,这一实现自然就变得相当简单了,同样是两步:
一、MainActivity设置singleTask
二、出口放置在MainActivity
代码如下:

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
    private TextView tv;
    private boolean doubleexit=false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode==KeyEvent.KEYCODE_BACK){
            if(doubleexit==true)
                this.finish();//退出应用

        else{
            Toast.makeText(this,"再按一次退出",Toast.LENGTH_SHORT).show();
            doubleexit=true;
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    doubleexit=false;//2秒没有返回动作则失效
                }
            },2000);
            return true;
        }
        }
        return super.onKeyDown(keyCode, event);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值