在Android开发的时候,需要给某按钮或者某事件赋予完全退出程序的方法。
Android中有一个很常用的方法是finish();
finish()可以返回Activity堆栈中的上一个Activity,即pop(),如果当前Activity已是最底层的Activit则会退出程序。
这就引出一个问题了:
如果当Activity1 跳转到 Activity2 的时候,如果在Activity2中调用finish()其实只会回到Activity1而不是退出程序。这个时候调用finish显然就不行了。
一般网上比较常见的说法是用:
System.exit(0);
或是
android.os.Process.killProcess(android.os.Process.myPid())
经过试验过后发现并无效果。
其实以上方法在Android2.1中是可行的。
2.2以后统统作废,几经折腾,终于觅得终极解决方案:
- Intent startMain = new Intent(Intent.ACTION_MAIN);
- startMain.addCategory(Intent.CATEGORY_HOME);
- startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(startMain); System.exit(0);
- 这个方法很猛,可以直接回到android主界面,也算是可以解决一时只需了。
Intent startMain = new Intent(Intent.ACTION_MAIN); startMain.addCategory(Intent.CATEGORY_HOME); startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(startMain); System.exit(0); 这个方法很猛,可以直接回到android主界面,也算是可以解决一时只需了。
看到有说广播机制,发现是个好东东,能彻底解决这个问题,废话不说看代码:
- public abstract class EnterActivity extends BaseActivity {
- ...
- // 写一个广播的内部类,当收到动作时,结束activity
- private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- close();
- unregisterReceiver(this); // 这句话必须要写要不会报错,不写虽然能关闭,会报一堆错
- }
- };
- @Override
- public void onResume() {
- super.onResume();
- // 在当前的activity中注册广播
- IntentFilter filter = new IntentFilter();
- filter.addAction(Attribute.PAGENAME);
- registerReceiver(this.broadcastReceiver, filter); // 注册
- }
- /**
- * 关闭
- */
- public void close() {
- Intent intent = new Intent();
- intent.setAction(Attribute.PAGENAME); // 说明动作
- sendBroadcast(intent);// 该函数用于发送广播
- finish();
- }
- ...
- }
不过话说回来,这种退出的方式其实并不推荐。
Android大多应用没有退出的设计其实是有道理的,这和系统对进程的 调度机制有关系。如果你知道java,就能更清楚这机制了。其实和java的垃圾回收机制类似,系统有一个规则来回收内存。进行内存调度有个阀值,只有低 于这个值系统才会按一个列表来关闭用户不需要的东西。当然这个值默认设置得很小,所以你会看到内存老在很少的数值徘徊。但事实上他并不影响速度。相反加快 了下次启动应用的速度。这本来就是android标榜的优势之一,如果人为去关闭进程,没有太大必要。特别是使用自动关进程的软件。(这里解决了大家非要 关进程的误区!)
到这里有人会说了,那为什么内存少的时候运行大型程序会慢呢?其实很简 单,在内存剩余不多时打开大型程序,会触发系统自身的调进程调度策略,这是十分消耗系统资源的操作,特别是在一个程序频繁向系统申请内存的时候。这种情况 下系统并不会关闭所有打开的进程,而是选择性关闭,频繁的调度自然会拖慢系统。
那么,进程管理软件有无必要呢?有的。就是在运行大型程序之前,你可以手动关闭一些进程释放内存,可以显著的提高运行速度。但一些小程序,完全可交由系统自己管理。
谈到这里,可能有的朋友会问,如果不关程序是不是会更耗电。我就说说 android后台的原理,你就明白了。android的应用在被切换到后台时,它其实已经被暂停了,并不会消耗cpu资源,只保留了运行状态。所以为什 么有的程序切出去重进会到主界面。但是,一个程序如果想要在后台处理些东西,如音乐播放,它就会开启一个服务。服务可在后台持续运行,所以在后台耗电的也 只有带服务的应用了。这个在进程管理软件里能看到,标签是service。至于广播什么的我就不涉及了。所以没有带服务的应用在后台是完全不耗电的,没有 必要关闭。这种设计本来就是一个非常好的设计,下次启动程序时,会更快,因为不需要读取界面资源,何必要关掉他们抹杀这个android的优点呢?(告诉 我们如何合理使用进程管理软件)
还有一个,为什么android一个应用看起来那么耗内存。大家知 道,android上的应用是java,当然需要虚拟机,而android上的应用是带有独立虚拟机的,也就是每开一个应用就会打开一个独立的虚拟机。这 样设计的原因是可以避免虚拟机崩溃导致整个系统崩溃,但代价就是需要更多内存。(跟塞班也不一样,安卓不容易死机重启)
以上这些设计确保了android的稳定性,正常情况下最多单个程序崩 溃,但整个系统不会崩溃,也永远没有内存不足的提示出现。大家可能是被windows毒害得太深了,总想保留更多的内存,但实际上这并不一定会提升速度, 相反却丧失了程序启动快的这一系统特色,很没必要。
最后一种通用的栈的方法:
android退出应用程序会调用 android.os.Process.killProcess(android.os.Process.myPid())或是 System.exit(0),这只是针对第一个Activity(也就是入口的Activity)时生效。如果有A,B,C三个Activity,而想 在B或C中Activity退出,调用上面的方法,往往会销毁当前的Activity返回上一个Activity。当然也可以逐个返回上一个 Activity,直到跳转到入口的Activity,最后退出应用程序。但这样比较麻烦,而且逐个返回的体验并不友好。
网上比较流行的方法是定义栈,写一个ExitApplication类,利用单例模式管理Activity,在每个在Activity的 onCreate()方法中调用ExitApplication.getInstance().addActivity(this)方法,在退出时调用 ExitApplication.getInstance().exit()方法,就可以完全退出应用程序了。
ExitApplication类
代码如下:
- import java.util.LinkedList;
- import java.util.List;
- import android.app.Activity;
- import android.app.Application;
- public class ExitApplication extends Application {
- private List activityList = new LinkedList();
- private static ExitApplication instance;
- private ExitApplication()
- {
- }
- //单例模式中获取唯一的ExitApplication实例
- public static ExitApplication getInstance()
- {
- if(null == instance)
- {
- instance = new ExitApplication();
- }
- return instance;
- }
- //添加Activity到容器中
- public void addActivity(Activity activity)
- {
- activityList.add(activity);
- }
- //遍历所有Activity并finish
- public void exit()
- {
- for(Activity activity:activityList)
- {
- activity.finish();
- }
- System.exit(0);
- }
- }