如何让 App 在崩溃后自动重启
来源:互联网 发布:windows xp qq影音下载 编辑:程序博客网 时间:2024/05/17 06:39
最近公司的项目出现了一点棘手的问题,由于某种未知的原因,该 App 在网络连接上出现了问题,只能用轮询来进行网络请求。但是这种方式会使得 App 每隔半小时就崩溃一次,最后无奈之下,决定让 App 在崩溃后自动重启。
当然了,这只是无法可想之下的应急手段,如果可以解决网络推送的毛病就好了……
下面是对于网络上资料的总结。
捕捉异常处理类
网络上对于程序崩溃的处理已经说得很清楚了(虽然看起来都是同一个人写的代码),就是利用 Thread.UncaughtExceptionHandler 类,重写其中的 uncaughtException(Thread thread, Throwable ex) 方法。
自定义异常处理类
如上所述,关键在于重写 uncaughtException(Thread thread, Throwable ex):
@Override public void uncaughtException(Thread thread, Throwable ex) { if (!handleException(ex) && mUncaughtExceptionHandler != null) { // 若是用户没有设置异常处理,则让系统默认的类来处理异常 mUncaughtExceptionHandler.uncaughtException(thread, ex); } else { // 进行自定义的方法 // 设置定时任务,1秒后重启此 App Intent intent = new Intent(context, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent restartIntent = PendingIntent.getActivity(context, 0, intent, 0); AlarmManager mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); mAlarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent); // 移除当前任务 myApplication.finishActivity(); } }
其中有一个 handleException(Throwable ex) 方法,同样是自己定义的,意在对崩溃是抛出的异常进行处理,例如打印日志、上传崩溃信息等等。
private boolean handleException(Throwable ex) { if (ex == null) { return false; } // 此处可以进行一些更为复杂的请求,例如打印崩溃信息日志等 // 这里弹出提示信息 new Thread() { @Override public void run() { Looper.prepare(); Toast.makeText(context, "很抱歉,程序崩溃了,一秒钟后重启。", Toast.LENGTH_SHORT).show(); Looper.loop(); } }.start(); return true; }
自定义 Application
异常处理类里需要用到的 Context 对象,应当为 Application。
网上很多的代码都是使用 getApplicationContext() 或是 Application.getBaseContext() ,但是我这里在创建 Toast 、Intent 的时候就会出现无法创建的情况,导致后续代码不能执行,异常处理类自然不能正常工作。
因此,建议在程序入口传入 Application 的 Context 对象,后续直接使用此对象。
@Override public void onCreate() { super.onCreate(); // 将自定义的异常处理类设为默认 MyUncaughtExceptionHandler catchException = new MyUncaughtExceptionHandler(getApplicationContext()); Thread.setDefaultUncaughtExceptionHandler(catchException); }
自定义的 Application 很简单,声明了使用自定义的类来捕获崩溃异常。
最后,别忘了在 Manifest 里对 Application 进行初始化。
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mouzhai.test"> <application android:name=".MyApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application></manifest>
完整代码
MainActivity.class
这里简单地设置了一个按钮,点击按钮就会使程序崩溃。
private MyApplication myApplication; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myApplication = new MyApplication(); myApplication.addActivity(this); btnCrash = (Button) findViewById(R.id.btn_crash); btnCrash.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 在子线程中改变 UI,会导致程序崩溃 new Thread(new Runnable() { @Override public void run() { btnCrash.setText("ccccccccccccccccc"); } }).start(); } }); } @Override protected void onDestroy() { super.onDestroy(); myApplication.removeActivity(this); }
MyApplication.class
/** * 在此初始化一些必要的逻辑,并定义了一些管理 Activity 的方法 * 需要获取 Application 级别 Context 对象的方法可以设置在这里 * <p> * Created by Mouzhai on 2017/4/11. */public class MyApplication extends Application { List<Activity> list = new ArrayList<>(); @Override public void onCreate() { super.onCreate(); // 将自定义的异常处理类设为默认 MyUncaughtExceptionHandler catchException = new MyUncaughtExceptionHandler(getApplicationContext()); Thread.setDefaultUncaughtExceptionHandler(catchException); } /** * 当 Activity 结束时,从列表中移除 */ public void removeActivity(Activity a) { list.remove(a); } /** * 向列表中添加 Activity */ public void addActivity(Activity a) { list.add(a); } /** * 结束列表中的所有 Activity */ public void finishActivity() { for (Activity activity : list) { if (null != activity) { activity.finish(); } } // 结束当前进程 android.os.Process.killProcess(android.os.Process.myPid()); }}
MyUncaughtExceptionHandler.class
/** * 自定义异常处理类 * <p> * Created by Mouzhai on 2017/4/11. */public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { private Context context; private Thread.UncaughtExceptionHandler mUncaughtExceptionHandler; private MyApplication myApplication; public MyUncaughtExceptionHandler(Context context) { this.context = context; mUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();// 获取系统默认的异常处理类 myApplication = new MyApplication(); } @Override public void uncaughtException(Thread thread, Throwable ex) { if (!handleException(ex) && mUncaughtExceptionHandler != null) { // 若是用户没有设置异常处理,则让系统默认的类来处理异常 mUncaughtExceptionHandler.uncaughtException(thread, ex); } else { // 进行自定义的方法 // 设置定时任务,1秒后重启此 App Intent intent = new Intent(context, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent restartIntent = PendingIntent.getActivity(context, 0, intent, 0); AlarmManager mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); mAlarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent); // 移除当前任务 myApplication.finishActivity(); } } /** * 对于抛出的异常进行处理,例如打印日志、发送文件给服务器等等 * * @param ex 导致崩溃的异常 * @return 若在此处理了异常,则返回 true,否则返回 false */ private boolean handleException(Throwable ex) { if (ex == null) { return false; } // 此处可以进行一些更为复杂的请求,例如打印崩溃信息日志等 // 这里弹出提示信息 new Thread() { @Override public void run() { Looper.prepare(); Toast.makeText(context, "很抱歉,程序崩溃了,一秒钟后重启。", Toast.LENGTH_SHORT).show(); Looper.loop(); } }.start(); return true; }}
大功告成!不过最后还是想给自己的项目烧柱香……
- 如何让 App 在崩溃后自动重启
- APP崩溃后自动重启
- android app崩溃后自动重启
- 【Android】App应用崩溃(Crash/Force Close)之后如何让它自动重启?
- app崩溃后捕获异常或自动重启
- app崩溃后捕获异常或自动重启
- app崩溃后捕获异常或自动重启
- Android 如何自定义CrashHandler与崩溃后自动重启
- Android APP进程保护,在APP进程异常崩溃后能够重启
- Android开发之app崩溃后捕获异常或自动重启
- 如何让service被管理器杀死后自动重启
- 如何让service被管理器杀死后自动重启
- 如何让service被管理器杀死后自动重启
- 如何让service被管理器杀死后自动重启
- 如何让service被管理器杀死后自动重启
- 如何让service被管理器杀死后自动重启
- 进程意外崩溃,如何自动重启
- zsh如何让alias在重启ssh后生效
- 生成19纯数字的字符串或者生成32位UUID
- QT模块简介
- Eclipse下,修改MAVEN 中央仓库地址,解决maven下载慢问题
- SpringMVC MultipartFile文件上传
- Android 线程池
- 如何让 App 在崩溃后自动重启
- Eddy的难题
- Gps开发实战——卫星数量获取
- Android scrollview嵌套问题
- Struts2标签:<s:password>回显
- 设计模式:策略模式
- Nginx简介
- node.js搭建https服务
- gulp创建一个文件基本步骤