前段期间,参加比赛做项目时遇到了一个问题:Android中应用程序弹出退出对话框退出应用程序时,老是出现上一个Activity,于是将在Activity跳转时将其finish()掉,结果还是不行!寻其原因:原来项目中有好多Activity用来显示界面,之间还掺扎着数据信息的交流,我们知道Activity是以栈的方式存放,要想将程序退出,自然得将众多Activity销毁掉了!

后来在网上查阅了一下,找到了解决方法,在此总结一下前辈们知识,使其更加系统化!

 

 

1.任务管理器方法(ActivityManager):

首先要说明该方法运行在Android 1.5 API Level为3以上才可以,同时需要权限




1


2




​ActivityManager am = (ActivityManager)getSystemService (Context.ACTIVITY_SERVICE);​


​am.restartPackage(getPackageName());​



系统会将,该包下的 ,所有进程,服务,全部杀掉,就可以杀干净了,要注意加上




1




​<​​​​uses-permission​​ ​​android:name=\"android.permission.RESTART_PACKAGES\"></​​​​uses-permission​​​​>​



 

2.Dalvik VM的本地方法:

 




1


2




​android.os.Process.killProcess(android.os.Process.myPid())    ​​​​//获取PID​


​System.exit(​​​​0​​​​);   ​​​​//常规java、c#的标准退出法,返回值为0代表正常退出​



 

3.一种比较流行的Android经典完美退出方法:

 

使用单例模式创建一个Activity管理对象,该对象中有一个Activity容器(具体实现自己处理,使用LinkedList等)专门负责存储新开启的每一个Activity,并且容易理解、易于操作,非常不错!

 

 

A.MyApplication类(储存每一个Activity,并实现关闭所有Activity的操作)

 




1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24




​public​​ ​​class​​ ​​MyApplication ​​​​extends​​ ​​Application {​


​//对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList实现了基于动态数组的数据结构,要移动数据。LinkedList基于链表的数据结构,便于增加删除 ​


​private​​ ​​List<Activity> activityList = ​​​​new​​ ​​LinkedList<Activity>();​


​private​​ ​​static​​ ​​MyApplication instance;​


​private​​ ​​MyApplication(){ }​


​//单例模式中获取唯一的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();​


​}​


​System.exit(​​​​0​​​​);​


​}​


​}​



 

B.在每一个Activity中的onCreate方法里添加该Activity到MyApplication对象实例容器中

 

 




1




​MyApplication.getInstance().addActivity(​​​​this​​​​);​



C.在需要结束所有Activity的时候调用exit方法

 




1




​MyApplication.getInstance().exit();​



 

4.广播方式:

 

A. MyAcitivty类说明:Acitivty的子类,基础该类的子类必须实现onCreate 方法,在该类中注册了一个BroadcastReceiver 用于接收退出消息,在接收到消息之后结束自身

 




1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25




​public​​ ​​abstract ​​​​class​​ ​​MyAcitivty ​​​​extends​​ ​​Activity {​


​/**负责各个具体 Activity 的显示**/​


​public​​ ​​abstract ​​​​void​​ ​​onCreate();​


​@Override​


​public​​ ​​void​​ ​​onCreate(​​​​final​​ ​​Bundle savedInstanceState) {​


​// TODO Auto-generated method stub​


​super​​​​.onCreate(savedInstanceState);​


​onCreate();​


​RegListener();​


​}​


​/**注册退出事件监听**/​


​public​​ ​​void​​ ​​RegListener() {​


​ExitListenerReceiver exitre = ​​​​new​​ ​​ExitListenerReceiver();​


​IntentFilter intentfilter = ​​​​new​​ ​​IntentFilter();​


​intentfilter.addAction(​​​​this​​​​.getPackageName() + ​​​​"."​


​+ ​​​​"ExitListenerReceiver"​​​​);​


​this​​​​.registerReceiver(exitre, intentfilter);​


​}​


​class​​ ​​ExitListenerReceiver ​​​​extends​​ ​​BroadcastReceiver {​


​@Override​


​public​​ ​​void​​ ​​onReceive(Context context, Intent i) {​


​((Activity) context).finish();​


​}​


​}​


​}​



 

B.自己的Activity都继承MyAcitivty,到需要退出程序的时候发送广播

 




1


2




​Intent intent = ​​​​new​​ ​​Intent(context.getPackageName()+​​​​".ExitListenerReceiver"​​​​);​


​context.sendBroadcast(intent);​



即可。

 

5.一个技巧方式:

 

A.首先设定一个公用的class: Setting.java,定义一个静态类成员




1




​public​​ ​​boolean ​​​​static​​ ​​isCloseAll=​​​​false​​​​;​



B.然后,在每一个Activity的onResume()加入这一个:

 




1


2


3


4


5




​@Override​


​onResume() {​


​super​​​​.onResume();​


​if​​​​(Setting.isCloseAll) finish();​


​}​



C.当最后一个Activity需要结束整个程序便执行:




1


2




​Setting.isCloseAll=​​​​true​​​​;​


​finish();​



 

6.捕获空指针异常

A.通过异常并在Application的子类中重新注册Thread的 Thread.UncaughtExceptionHandler接口:

 




1


2


3


4


5


6


7


8


9


10




​package​​ ​​com.example.android_uncatchexception;​


​import​​ ​​android.app.Application;​


​public​​ ​​class​​ ​​MyCrashApplication ​​​​extends​​ ​​Application {​


​@Override​


​public​​ ​​void​​ ​​onCreate() {​


​super​​​​.onCreate();​


​//程序一启动,就将未捕获异常初始化​


​CrashHandler.getInstance().init(getApplicationContext());​


​}​


​}​



注:记得注册Application

 

B.自定义异常捕获类:




1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36


37


38


39


40


41


42


43


44


45


46




​package​​ ​​com.example.android_uncatchexception;​


​import​​ ​​java.lang.Thread.UncaughtExceptionHandler;​


​import​​ ​​android.content.Context;​


​import​​ ​​android.util.Log;​


​/**​


​* 自定义异常捕获类​


​*​


​* @author ZHF​


​*/​


​public​​ ​​class​​ ​​CrashHandler ​​​​implements​​ ​​UncaughtExceptionHandler {​


​public​​ ​​static​​ ​​final​​ ​​String​​ ​​TAG = ​​​​"CrashHandler"​​​​;​


​// 程序的Context对象​


​private​​ ​​Context mContext;​


​/** 单例模式 **/​


​private​​ ​​CrashHandler() {​


​}​


​/** 懒汉式 **/​


​private​​ ​​static​​ ​​class​​ ​​CrashHolder {​


​static​​ ​​final​​ ​​CrashHandler crashHandler = ​​​​new​​ ​​CrashHandler();​


​}​


​public​​ ​​static​​ ​​CrashHandler getInstance() {​


​return​​ ​​CrashHolder.crashHandler;​


​}​


​public​​ ​​void​​ ​​init(Context context) {​


​mContext = context;​


​// 设置该CrashHandler为程序的默认处理器​


​Thread.setDefaultUncaughtExceptionHandler(​​​​this​​​​);​


​}​


​@Override​


​public​​ ​​void​​ ​​uncaughtException(Thread thread, Throwable ex) {​


​Log.d(TAG,​


​"uncaughtException--->thread"​​ ​​+ thread + ​​​​" name: "​


​+ thread.getName() + ​​​​" id: "​​ ​​+ thread.getId() + ​​​​"exception--->"​​ ​​+ ex);​


 


​String​​ ​​threadName = thread.getName();​


​if​​​​(​​​​"main"​​​​.equals(threadName)) {​


​Log.d(TAG, ​​​​"在主线程的崩溃!"​​​​);​


​}​​​​else​​ ​​{​


​//这里我们根据thread name来进行区别对待:可以将异常信息写入文件供以后分析​


​Log.d(TAG, ​​​​"在子线程中崩溃!"​​​​);​


​}​


 


​android.os.Process.killProcess(android.os.Process.myPid()); ​​​​//杀死该进程​


​System.exit(​​​​0​​​​); ​​​​//退出​


​}​


​}​



C.在要退出的地方制造空指针异常即可实现闪退,并且不会弹出ANR对话框

 




1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25




​package​​ ​​com.example.android_uncatchexception;​


​import​​ ​​android.os.Bundle;​


​import​​ ​​android.app.Activity;​


​import​​ ​​android.view.View;​


​import​​ ​​android.view.View.OnClickListener;​


​import​​ ​​android.widget.Button;​


​public​​ ​​class​​ ​​MainActivity ​​​​extends​​ ​​Activity {​


 


​Button mBtn;​


​String​​ ​​str; ​​​​//不要初始化,为了下面制造空指针异常​


​@Override​


​protected​​ ​​void​​ ​​onCreate(Bundle savedInstanceState) {​


​super​​​​.onCreate(savedInstanceState);​


​setContentView(R.layout.activity_main);​


 


​mBtn = (Button) ​​​​this​​​​.findViewById(R.id.button1);​


​mBtn.setOnClickListener(​​​​new​​ ​​OnClickListener() {​


​@Override​


​public​​ ​​void​​ ​​onClick(View v) {​


​//NullPointerException​


​System.out.println(str);​


​}​


​});​


​}​


​}​



 

 

 

7.网上还有一些其他方式:

A.restartPackage、

B. killBackgroundProcesses