Android退出应用最优雅的方式(改进版)(转)

我们先来看看几种常见的退出方法(不优雅的方式)

一、容器式

     建立一个全局容器,把所有的Activity存储起来,退出时循环遍历finish所有Activity
import java.util.ArrayList;
import java.util.List; import android.app.Activity;
import android.os.Bundle; public class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 添加Activity到堆栈
AtyContainer.getInstance().addActivity(this);
} @Override
protected void onDestroy() {
super.onDestroy();
// 结束Activity&从栈中移除该Activity
AtyContainer.getInstance().removeActivity(this);
} } class AtyContainer { private AtyContainer() {
} private static AtyContainer instance = new AtyContainer();
private static List<Activity> activityStack = new ArrayList<Activity>(); public static AtyContainer getInstance() {
return instance;
} public void addActivity(Activity aty) {
activityStack.add(aty);
} public void removeActivity(Activity aty) {
activityStack.remove(aty);
} /**
* 结束所有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();
} }

这种方法比较简单, 但是可以看到activityStack持有这Activity的强引用,也就是说当某个Activity异常退出时,activityStack没有即使释放掉引用,就会导致内存问题,接下来我们看一种类似的方式,但是会稍微优雅一点点

二、广播式

  通过在BaseActivity中注册一个广播,当退出时发送一个广播,finish退出
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) {
BaseActivity.this.finish();
} } }

  

三、进程式

    通过直接杀死当前应用的进程来结束应用,简单粗暴,而且有(wu)效!

    android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0); ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
manager.killBackgroundProcesses(getPackageName()); 这三种都能达到同样的效果,但是在模拟器上都会弹出 Unfortunately , XXX has stopped 消息提示框,但确实能退出应用。部分真机直接失效,只能finish当前Activity(比如我手上这台小米note,国产的几款ROM fw层改动太多,使用这种方式需慎重) 。

四、 RS优雅式

     什么是RS式呢?即Receiver+singleTask 。我们知道Activity有四种加载模式,而singleTask就是其中的一种,使用这个模式之后,当startActivity时,它先会在当前栈中查询是否存在Activity的实例,如果存在,则将其至于栈顶,并将其之上的所有Activity移除栈。我们打开一个app,首先是一个splash页面,然后会finish掉splash页面。跳转到主页。然后会在主页进行N次的跳转,期间会产生数量不定的Activity,有的被销毁,有的驻留在栈中,但是栈底永远是我们的HomeActivity。这样就让问题变得简单很多了。我们只需两步操作即可优雅的实现app的退出。

   1、在HomeActivity注册一个退出广播,和第二个广播式一样,但是这里只需要在HomeActivity一个页面注册即可。

   2、设置HomeActivity的启动模式为singleTask。

当我们需要退出的时候只需要startActivity(this,HomeActivity,class), 再发送一个退出广播。上面代码首先会把栈中HomeActivity之上的所有Activity移除出栈,然后接到广播finish自己。一切OK ! 没有弹框,不用考虑机型Rom适配。不会有内存问题,就是那么的优雅,简单!

五、SingleTask改版式

  和一些小伙交流之后,很多小伙伴说注册广播略显麻烦,在楼下的小伙伴提出了一种更简单的方式,思路也很简单,
1、设置MainActivity的加载模式为singleTask
2、重写MainActivity中的onNewIntent方法
3、需要退出时在Intent中添加退出的tag
由于很多小伙伴对源码需求比较热切,我们这里就直接以代码的形式为大家讲解这种方式

第一步设置MainActivity的加载模式为singleTask

 android:launchMode="singleTask"

第二步重写onNewIntent()方法

private static final String TAG_EXIT = "exit";

    @Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent != null) {
boolean isExit = intent.getBooleanExtra(TAG_EXIT, false);
if (isExit) {
this.finish();
}
}
}

第三步 退出

Intent intent = new Intent(this,MainActivity.class);
intent.putExtra(MainActivity.TAG_EXIT, true);
startActivity(intent);

六、懒人式 
这种方式更加简单,只需要如下两步操作 
1、将MainActivity设置为singleTask 
2、将退出出口放置在MainActivity 
我们可以看到很多应用都是双击两次home键退出应用,就是基于这样的方式来实现的,这里在贴一下如何处理连续两次点击退出的源码

private boolean mIsExit;
@Override
/**
* 双击返回键退出
*/
public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) {
if (mIsExit) {
this.finish(); } else {
Toast.makeText(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);
}

Android退出应用最优雅的方式(改进版)的更多相关文章

  1. AJPFX分析Android退出应用最优雅的方式

    什么是RS式呢?即Receiver+singleTask .我们知道Activity有四种加载模式,而singleTask就是其中的一种,使用这个模式之后,当startActivity时,它先会在当前 ...

  2. 优雅退出 Android 应用程序的 6 种方式

    我们先来看看几种常见的退出方法(不优雅的方式) 一.容器式 建立一个全局容器,把所有的Activity存储起来,退出时循环遍历finish所有Activity import java.util.Arr ...

  3. Android APP新的“优雅”退出方式--EventBus大显身手

    最近在研究eventBus..很多小伙伴不知道他有什么用.. 前篇介绍了EventBus的基本使用 这里简单举一个例子,就是退出APP 转载请注明出处:http://blog.csdn.net/win ...

  4. Android 退出多Activity的application的方式

    在开发过程中,我们常常需要一个退出功能,来退出该应用的所有Activity.下面,我们列举一些退出应用的几种方式.以下用的源码点击查看源码地址 欢迎star,欢迎fork 利用ActivityCont ...

  5. android 启动 service 的两种方式,及什么时候用哪个 android 什么时候用bindService

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha android  什么时候用bindService ============ 启动方式有 ...

  6. java线程基础巩固---Thread中断Interrupt方法学习&采用优雅的方式结束线程生命周期

    Interrupt学习: 在jdk中关于interrupt相关方法有三个,如下: 关于上面的疑问会在稍后进行阐述滴,下面看代码: 编译运行: 应该说是t线程为啥在被打断之后没有退出,还是在运行状态,这 ...

  7. Android退出时关闭所有Activity的方法

    Android退出时,有的Activity可能没有被关闭.为了在Android退出时关闭所有的Activity,设计了以下的类: //关闭Activity的类 public class CloseAc ...

  8. Android数据的四种存储方式SharedPreferences、SQLite、Content Provider和File (一) —— 总览

    Android数据的四种存储方式SharedPreferences.SQLite.Content Provider和File (一) —— 总览   作为一个完成的应用程序,数据存储操作是必不可少的. ...

  9. Android网络之数据解析----SAX方式解析XML数据

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

随机推荐

  1. 使用Application Loader上传APP流程解读[APP公布]

    本文仅仅是提供一个公布流程的总体思路.假设没有公布经验.建议阅读苹果官方公布文档或者Google搜索具体教程. 1.申请开发人员账号:99美金的(须要信用卡支付),详细流程网上有非常多样例.自行搜索. ...

  2. ELK之jason配置nginx文件等多个配置文件

    [root@web02 ~]# cat /etc/logstash/conf.d/nginx.conf input { file { path => "/var/log/nginx/a ...

  3. grep -rl tttt /data/ 命令在 /data 目录下面搜寻包含tttt字符的命令

    grep --help -R, -r, --recursive equivalent to --directories=recurse -l, --files-with-matches print o ...

  4. PHP-Socket-阻塞与非阻塞,同步与异步概念的理解

    1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式:同步:      所谓同步,就是在发出一个功能调用时,在没 ...

  5. python pymysql安装

    ==================pymysql=================== 由于 MySQLdb 模块还不支持 Python3.x,所以 Python3.x 如果想连接MySQL需要安装 ...

  6. 如何更好的利用Node.js的性能极限

    通过使用非阻塞.事件驱动的I/O操作,Node.js为构建和运行大规模网络应用及服务提供了很好的平台,也受到了广泛的欢迎.其主要特性表现为能够处理庞大的并且高吞吐量的并发连接,从而构建高性能.高扩展性 ...

  7. Linux下文件的基本操作

    文件的基本操作 新建和删除文件夹 命令#mkdir /file 在当前目录创建file文件夹 命令#rmdir /file 删除当前目录下file文件夹 复制和移动文件 命令#cp text/file ...

  8. 我自己曾经经历的CMMI3认证通过关于软件测试的访谈【转载】

    转自<http://blog.csdn.net/jcy58/article/details/51908884> 因为当初我在公司里是负责软件测试工作的,所以CMMI3和测试相关的访谈,就是 ...

  9. 【BZOJ2844】albus就是要第一个出场 高斯消元求线性基

    [BZOJ2844]albus就是要第一个出场 Description 已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n }, S 的幂集2 ...

  10. 【BZOJ3689】异或之 堆+可持久化Trie树

    [BZOJ3689]异或之 Description 给定n个非负整数A[1], A[2], ……, A[n].对于每对(i, j)满足1 <= i < j <= n,得到一个新的数A ...