原文网址:http://www.yoyong.com/archives/199

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://smallwoniu.blog.51cto.com/3911954/1248643

前段期间,参加比赛做项目时遇到了一个问题: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

不常用,大家可以自行参考哦~

 

 

 

 

 

本文出自 “狂奔的蜗牛” 博客,请务必保留此出处http://smallwoniu.blog.51cto.com/3911954/1248643

【转】Android应用程序完全退出的更多相关文章

  1. Android企业级程序完全退出的解决方案

    一.问题描述 在平常开发的过程中可以发现,很多开发者对于程序的退出都没有去认真的解决.一般要么是一个简单的finish(只是退出当前的activity),要么是其他的方法,比如: 1.第一种方法:首先 ...

  2. android捕获程序异常退出

    今天看到迅雷动漫里面一个CrashHandler 的类,我猜是崩溃处理类.进去一看.果然.顺便学习一下. Android系统的"程序异常退出",给应用的用户体验造成不良影响.为了捕 ...

  3. Android企业级程序完全退出的解决方案【转】

    http://blog.csdn.net/wangjinyu501/article/details/8763552 问题描述 在平常开发的过程中可以发现,很多开发者对于程序的退出都没有去认真的解决.一 ...

  4. Android程序完全退出的三种方法

    很多网友可能发现自己的Android程序有很多Activity,比如说主窗口A,调用了子窗口B,在B中如何关闭整个Android应用程序呢? 这里Android123给大家三种比较简单的方法实现. 首 ...

  5. 你真的有必要退出吗——再说Android程序的退出功能

    转自你真的有必要退出吗--再说Android程序的退出功能 搞Android开发有一段时间了,相信很多从Windows开发过来的Android程序员都习惯性地会跟我一样遇到过同一个问题:如何彻底退出程 ...

  6. 如何完全退出android应用程序

    当一个android应用程序包含多个activity时,要完全退出android应用程序,便要销毁掉所有的activity,下面是一种网上流传的比较经典完美的方法: 首先要定义一个继承Applicat ...

  7. Android系统的“程序异常退出”[转]

    在应用运行过程中,有很多异常可能会发生,而我们希望在异常发生的时候第一时间的保存现场. 如何处理未捕获的异常呢? 首先我们要实现一个接口  java.lang.Thread.UncaughtExcep ...

  8. Android卸载程序之后跳转到指定的反馈页面

    一个应用被用户卸载肯定是有理由的,而开发者却未必能得知这一重要的理由,毕竟用户很少会主动反馈建议,多半就是用得不爽就卸,如果能在被卸载后获取到用户的一些反馈,那对开发者进一步改进应用是非常有利的.目前 ...

  9. Eclipse+CDT+GDB调试android NDK程序(转)

    Eclipse+CDT+gdb调试android ndk程序 先介绍一下开发环境,在这个环境下,up主保证是没有问题的. ubuntu 11.10 eclipse 3.7(indego) for ja ...

随机推荐

  1. SQL 建立临时表进行查询

    SELECT min (maxrank) as minofmaxrank FROM (SELECT max(rank) as maxrank FROM tbl_core_staff WHERE st_ ...

  2. [功能帮助类] 最新的Functions 类 (转载)

    代码 using System; using System.Collections.Generic; using System.Text; using System.Security.Cryptogr ...

  3. python基础知识七

    我们会使用raw_input和print语句来完成这些功能. 对于输出,也可以使用多种多样的str(字符串)类. 例如使用rjust方法来得到一个按一定宽度右对齐的字符串. 可以通过创建一个file类 ...

  4. 分享一张oracle scan图

  5. sql server抓取表结构的语句

    sql server 2008抓取方法: ---------------------------------------   SELECT      表名 = Case When A.colorder ...

  6. Android 网络通信 HTTP

    摘要 1. Http GET 方法访问网站 2. Http POST访问网站 3. HttpClient进行Get方式通信 4. HttpClient进行Post方式通信 -------------- ...

  7. 搬瓦工vps搭建vpn

    一.下载centos6一键安装包 wget --no-check-certificate https://raw.githubusercontent.com/teddysun/across/maste ...

  8. js一些方法的扩展

    //JS扩展方法与C#的扩展方法非常相似,也是可以链式调用的,也是通过对某个类的扩展写法来实现.这个东西非常好用,如果将预先写好的方法放到一个js里面引用的话,那么后面写js将非常有趣. //下面给出 ...

  9. Java IO学习总结

    Java IO流学习总结 Io流的内容比较多 ,大致可以分为字节流和字符流,其中为了提高效率又用到了缓冲区. Java流操作有关的类或接口: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合, ...

  10. Codeforces Round #205 (Div. 2) : A

    题意: 要求找到最少次数的交换次数使得两组数都是偶数: 很明显答案要么是0,要么是1,或者不管怎么交换都不行(-1): 所以: #include<cstdio> #define maxn ...