【移动开发】Android应用程序完全退出

简介:

前段期间,参加比赛做项目时遇到了一个问题: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方法里添加该ActivityMyApplication对象实例容器中

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.然后,在每一个ActivityonResume()加入这一个:

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

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




     本文转自zhf651555765 51CTO博客,原文链接:http://blog.51cto.com/smallwoniu/1248643,如需转载请自行联系原作者




相关文章
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
1712 4
|
存储 Android开发
如何查看Flutter应用在Android设备上已被撤销的权限?
如何查看Flutter应用在Android设备上已被撤销的权限?
843 64
|
存储 Android开发 数据安全/隐私保护
如何在Android设备上撤销Flutter应用程序的所有权限?
如何在Android设备上撤销Flutter应用程序的所有权限?
1156 64
|
缓存 Android开发 开发者
Flutter环境配置完成后,如何在Android设备上运行Flutter应用程序?
Flutter环境配置完成后,如何在Android设备上运行Flutter应用程序?
3009 62
|
开发工具 Android开发 开发者
在Android设备上运行Flutter应用程序时,如果遇到设备未授权的问题该如何解决?
在Android设备上运行Flutter应用程序时,如果遇到设备未授权的问题该如何解决?
1193 61
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
1144 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
667 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
IDE 开发工具 Android开发
移动应用开发之旅:探索Android和iOS平台
在这篇文章中,我们将深入探讨移动应用开发的两个主要平台——Android和iOS。我们将了解它们的操作系统、开发环境和工具,并通过代码示例展示如何在这两个平台上创建一个简单的“Hello World”应用。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧,帮助你更好地理解和掌握移动应用开发。
498 17
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
507 14
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
380 13