Android退出应用程序方法总结

  1. finish方法
    finish();
    该方法只是结束当前Activity,系统将最上面的Activity移出了栈,并没有清理占用的资源。如果栈内有很多Activity 的话,使用该方法显得有点捉襟见肘了,没办法一次移出全部Activity,并且没有立即释放内存,活动的资源也没有被清理。

  2. 进程式
    (1)KillProcess():
    可以杀死当前应用活动的进程,这一操作将会把所有该进程内的资源(包括线程全部清理掉)。 当然,由于ActivityManager时刻监听着进程,一旦发现进程被非正常Kill,它将会试图去重启这个进程。
    android.os.Process.killProcess(android.os.Process.myPid());

    (2)System.exit():
    Java中结束进程的方法,调用它将关闭当前的JVM虚拟机。
    System.exit(0);//正常退出
    System.exit(1);//非正常退出
    KillProcess() 和 System.exit(),许多人都使用过,当你栈里只有一个Activity的时候,这个措施是行之有效的。但当关闭多个Activity的时候,栈里有多个Activity时,这两个方法就不起作用了。
    因为通过杀进程方式退出,会被系统认为异常退出,会保存应用的一些状态信息比如Activity运行栈,然后会恢复这个应用。当恢复一个Android应用程序时,会先从栈里面移除异常的Activity,相当于Back键操作。

  3. 根据Activity的生命周期
    Android的窗口类提供了历史栈,可以通过stack的原理来巧妙的实现。在A窗口打开B窗口的时候,在Intent中直接加入标识Intent.FLAG_ACTIVITY_CLEAR_TOP,这样开启B时,会清除该进程空间的所有Activity。
    1)在A窗口中调用该方法跳转到B窗口:
    Intent intent = new Intent();
    intent.setClass(AActivity.this,BActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(intent);
    2)在B窗口退出时直接使用 finish 方法即可全部退出
    finish();

  4. 任务管理器
    系统将终止一切和这个程序包关联的,所有共享同一 uid 的 process全部杀掉,还会停止相关的服务,并且会发送一个广播。

    ActivityManager am = (ActivityManager)getSystemService (Context.ACTIVITY_SERVICE);
    am.killBackgroundProcesses(getPackageName());
    System.exit(0);
    注意事项:该方法虽然可以立即杀死与指定包相关联的所有后台进程,但是这些进程如果在将来某一时刻需要使用,便会重新启动。而且该方法只是结束后台进程的方法,不能结束当前应用移除所有的 Activity。如果需要退出应用,需要添加System.exit(0)方法一起使用,并且只限栈内只有一个Activity,如果有多个Activity时,正如上面方法2所说,就不起作用了。

  5. 任务栈式
    利用一个单例模式的Activity栈来管理所有Activity
    1)自定义 Application类,储存每一个Activity,并实现关闭所有Activity的操作

public class MyApplication extends Application {    
    private List<Activity> activityList = new LinkedList<Activity>();
    private static MyApplication instance;
    private MyApplication() {
    }
    @Override
    public void onCreate() {
        super.onCreate();
    }
    //单例模式中获取唯一的MyApplication实例
    public static MyApplication getInstance() {
        if(null == instance) {
            instance = new MyApplication();
        }
        return instance;
    } 
   //添加Activity到容器中
    public void addActivity(Activity activity)  {
        activityList.add(activity);
    }
   //遍历所有Activity并finish
    public void exit() {
        for(Activity activity:activityList) {
            activity.finish();
        }       
        activityList.clear();
    }
}

2)在父类BaseActivity中添加继承子类Activity到栈中

public class BaseActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 添加Activity到堆栈
        MyApplication.getInstance().addActivity(this);
    }
    ...
}

3)在需要结束所有Activity的时候调用 exit 方法
MyApplication.getInstance().exit();

  1. 容器式
    类似 5(任务栈式),自定义一个Actiivty栈,通过单例模式的Activity栈来管理所有Activity
    1)建立一个全局容器,把所有的Activity存储起来
public class BaseActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 添加Activity到堆栈
        AtyContainer.getInstance().addActivity(this);
    }
    ...
}

2)创建Activity管理类

public class AtyContainer {
    public AtyContainer() {
    }

    private static AtyContainer instance = new AtyContainer();
    private static List<Activity> activityStack = new ArrayList<Activity>();
    public static AtyContainer getInstance() {
        return instance;
    }

    /**
     * 添加Activity到堆栈
     */
    public void addActivity(Activity activity) {
        if (activityStack == null) {
            activityStack = new ArrayList<Activity>();
        }
        activityStack.add(activity);
    }

    /**
     * 移除指定的Activity
     */
    public void removeActivity(Activity activity) {
        if (activity != null) {
            activityStack.remove(activity);
            activity = null;
        }
    }
    /**
    * 结束所有Activity
    */
    public void finishAllActivity() {
        for (int i = 0, size = activityStack.size(); i < size; i++) {
            if (null != activityStack.get(i)) {
                activityStack.get(i).finish();
            }
        }
        activityStack.clear();
    }
}

3)在退出时循环遍历finish所有Activity
AtyContainer.getInstance().finishAllActivity();
方法 5(任务栈式)和 6(容器式),是目前许多人常用的,但是需要注意的是:activityStack持有Activity的强引用,当某个Activity异常退出时,activityStack没有及时释放掉引用,可能会导致内存问题。

  1. 清空堆栈
    1)设置MainActivity的加载模式为singleTask
android:launchMode="singleTask"
2)重写MainActivity中的onNewIntent方法
@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    if (intent != null) {
        boolean isExit = intent.getBooleanExtra("exit", false);
        if (isExit) {
            finish();
        }
    }
}

3)需要退出时在Intent中添加退出的Tag
/*退出程序/

protected void exit() {
    // 这里使用clear + new task的方式清空整个任务栈,只保留新打开的Main页面
    // 然后Main页面接收到退出的标志位exit=true,finish自己,这样就关闭了全部页面
    Intent intent = new Intent(this, MainActivity.class);
    intent.putExtra("exit", true);
    startActivity(intent);
}
  1. 销毁任务栈
    直接调用系统 API获取当前的任务栈,把里面的Activity全部销毁掉。不过该方法简单粗暴,需要API21(Android 5.0)以上才可以使用。
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void exitAPP() {
        ActivityManager activityManager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.AppTask> appTaskList = activityManager.getAppTasks();
        for (ActivityManager.AppTask appTask : appTaskList) {
            appTask.finishAndRemoveTask();
        }
    }
  1. 广播式
    通过在全局中注册一个广播,当退出时发送一个广播退出
    1)在BaseActivity中注册广播
public class BaseActivity extends Activity {

    private static final String EXITACTION = "action.exit";
    private ExitReceiver exitReceiver = new ExitReceiver();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        IntentFilter filter = new IntentFilter();
        filter.addAction(EXITACTION);
        registerReceiver(exitReceiver, filter);
    }

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

    class ExitReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            finish();
        }
    }

}

2)发送广播退出

public class MainActivity extends BaseActivity {
    private long exitTime = 0;
    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 && event.getAction() == KeyEvent.ACTION_DOWN) {
            if ((System.currentTimeMillis() - exitTime) > 2000) {
                Toast.makeText(MainActivity.this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
                exitTime = System.currentTimeMillis();
            } else {
                //发送广播退出程序
                Intent intent = new Intent("com.xxx.BaseActivity");
                intent.putExtra(EXITACTION, 1);
                sendBroadcast(intent);
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
}
  1. 懒人式
    1)将MainActivity设置为singleTask
    android:launchMode=“singleTask”
    2)将退出出口放置在MainActivity
    private boolean mIsExit;
    /*双击返回键退出/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        if (mIsExit) {
            this.finish();
        } else {
            Toast.makeText(MainActivity.this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
            mIsExit = true;
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    mIsExit = false;
                }
            }, 2000);
        }
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

  1. 退回系统桌面
    Android应用开发中,有一种场景,就是我们不希望用户直接按Back键退出Activity,而是希望应用隐藏到后台的假退出,类似于按Home键的效果。(例如QQ、微信等)
    方法一(java):
    /退出程序/
protected void exit() {
    Intent startMain = new Intent(Intent.ACTION_MAIN);
    startMain.addCategory(Intent.CATEGORY_HOME);
    startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(startMain);
    System.exit(0);
}

方法二(xml):

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xxx.xxx"   
    android:versionCode="1"
    android:versionName="1.0.1">
  <application>     
    <activity
        android:name="com.xxx.xxx.MainActivity"
        android:label="@string/app_name"
        android:launchMode="singleTask"
        android:clearTaskOnLaunch="true"
        android:stateNotNeeded="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.HOME" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity> 
   ...
  </application>
</manifest>

结语
以上整理了目前Android退出应用程序常见的一些方法,每个方法各有利弊,大家可以去实践下,看看其具体效果,然后根据自己的需要,选择适合自己的方式。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值