zoukankan      html  css  js  c++  java
  • 【转】Android应用程序完全退出

    原文网址: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

  • 相关阅读:
    javascript学习
    python学习计划
    利用spring的测试组建,测试bean
    log4j 输出完整的Exception信息
    根据身份证号,取得行政区划的Javascript实现
    软件全程建模1
    软件界面建模浅析
    RUP简介
    用例建模中的一个问题的讨论
    软件全程建模2
  • 原文地址:https://www.cnblogs.com/wi100sh/p/4374618.html
Copyright © 2011-2022 走看看