android 中处理崩溃异常并重启程序出现页面重叠的问题
来源:互联网 发布:php url encode 在线 编辑:程序博客网 时间:2024/05/18 03:50
android开发中经常会遇到程序异常,而已常常会遇到一出现异常APP就自动重启了,而已如果你的项目中应用到Fragment的切换的话,会出行页面重叠的现象。今天为了解决这个问题看了不少大牛的博客。最后终于把问题解决了,下面就把解决的方法做一个介绍。
总的问题解决定向是处理崩溃异常的方法。先说说我前面尝试的不成功的方法。
一、写一个类实现UncaughtExceptionHandler 接口
import android.app.AlarmManager;import android.app.PendingIntent;import android.content.Context;import android.content.Intent;import android.os.Looper;import android.util.Log;import android.widget.Toast;/** * Created by willkong on 2016/12/14. */public class UnCeHandler implements Thread.UncaughtExceptionHandler { private Thread.UncaughtExceptionHandler mDefaultHandler; public static final String TAG = "CatchExcep"; MyApplication application; public UnCeHandler(MyApplication application){ //获取系统默认的UncaughtException处理器 mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); this.application = application; } @Override public void uncaughtException(Thread thread, Throwable ex) { if(!handleException(ex) && mDefaultHandler != null){ //如果用户没有处理则让系统默认的异常处理器来处理 mDefaultHandler.uncaughtException(thread, ex); }else{ try{ Thread.sleep(2000); }catch (InterruptedException e){ Log.e(TAG, "error : ", e); } Intent intent = new Intent(application.getApplicationContext(), MainActivity.class); PendingIntent restartIntent = PendingIntent.getActivity( application.getApplicationContext(), 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK); //退出程序 AlarmManager mgr = (AlarmManager)application.getSystemService(Context.ALARM_SERVICE); mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent); // 1秒钟后重启应用 application.finishActivity(); } } /** * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. * * @param ex * @return true:如果处理了该异常信息;否则没有处理返回false. */ private boolean handleException(Throwable ex) { if (ex == null) { return false; } //使用Toast来显示异常信息 new Thread(){ @Override public void run() { Looper.prepare(); Toast.makeText(application.getApplicationContext(), "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_SHORT).show(); Looper.loop(); } }.start(); return true; }}
二、通过在android Application 这个全局类中处理异常,一般我们都会重写一个我们自己的Application继承Application。
import android.app.Activity;import android.app.Application;import java.util.ArrayList;/** * Created by willkong on 2016/12/14. */public class MyApplication extends Application { ArrayList<Activity> list = new ArrayList<Activity>(); @Override public void onCreate() { super.onCreate(); //设置该CrashHandler为程序的默认处理器 UnCeHandler catchExcep = new UnCeHandler(this); Thread.setDefaultUncaughtExceptionHandler(catchExcep); } /** * Activity关闭时,删除Activity列表中的Activity对象*/ public void removeActivity(Activity a){ list.remove(a); } /** * 向Activity列表中添加Activity对象*/ public void addActivity(Activity a){ list.add(a); } /** * 关闭Activity列表中的所有Activity*/ public void finishActivity(){ for (Activity activity : list) { if (null != activity) { activity.finish(); } } //杀死该应用进程 android.os.Process.killProcess(android.os.Process.myPid()); }}
人为的制造一个异常
import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;public class MainActivity extends AppCompatActivity implements View.OnClickListener { Button btn; TextView tv; private MyApplication application; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button)findViewById(R.id.btn); tv = (TextView)findViewById(R.id.tv); application = (MyApplication) getApplication(); application.addActivity(this); btn.setOnClickListener(this); } /** * 人为制造的异常*/ public void press(){ new Thread(new Runnable() { @Override public void run() { tv.setText("dfsd"); } }).start(); } @Override public void onClick(View v) { press(); }}
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.testapplication.MainActivity"> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /> <Button android:id="@+id/btn" android:layout_width="match_parent" android:layout_height="wrap_content" /></LinearLayout>
尝试二:
通用 application
1、收集所有 avtivity 用于彻底退出应用
2、捕获崩溃异常,保存错误日志,并重启应用
public class HKBaseApplication extends Application { // activity对象列表,用于activity统一管理 private List<Activity> activityList; // 异常捕获 protected boolean isNeedCaughtExeption = true;// 是否捕获未知异常 private PendingIntent restartIntent; private MyUncaughtExceptionHandler uncaughtExceptionHandler; private String packgeName; @Override public void onCreate() { super.onCreate(); activityList = new ArrayList<Activity>(); packgeName = getPackageName(); if (isNeedCaughtExeption) { cauchException(); } } // -------------------异常捕获-----捕获异常后重启系统-----------------// private void cauchException() { Intent intent = new Intent(); // 参数1:包名,参数2:程序入口的activity intent.setClassName(packgeName, packgeName + ".LoginActivity"); restartIntent = PendingIntent.getActivity(getApplicationContext(), -1, intent, Intent.FLAG_ACTIVITY_NEW_TASK); // 程序崩溃时触发线程 uncaughtExceptionHandler = new MyUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler); } // 创建服务用于捕获崩溃异常 private class MyUncaughtExceptionHandler implements UncaughtExceptionHandler { @Override public void uncaughtException(Thread thread, Throwable ex) { // 保存错误日志 saveCatchInfo2File(ex); // 1秒钟后重启应用 AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE); mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent); // 关闭当前应用 finishAllActivity(); finishProgram(); } }; /** * 保存错误信息到文件中 * * @return 返回文件名称 */ private String saveCatchInfo2File(Throwable ex) { Writer writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); ex.printStackTrace(printWriter); Throwable cause = ex.getCause(); while (cause != null) { cause.printStackTrace(printWriter); cause = cause.getCause(); } printWriter.close(); String sb = writer.toString(); try { DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); String time = formatter.format(new Date()); String fileName = time + ".txt"; System.out.println("fileName:" + fileName); if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { String filePath = Environment.getExternalStorageDirectory() + "/HKDownload/" + packgeName + "/crash/"; File dir = new File(filePath); if (!dir.exists()) { if (!dir.mkdirs()) { // 创建目录失败: 一般是因为SD卡被拔出了 return ""; } } System.out.println("filePath + fileName:" + filePath + fileName); FileOutputStream fos = new FileOutputStream(filePath + fileName); fos.write(sb.getBytes()); fos.close(); //文件保存完了之后,在应用下次启动的时候去检查错误日志,发现新的错误日志,就发送给开发者 } return fileName; } catch (Exception e) { System.out.println("an error occured while writing file..." + e.getMessage()); } return null; } // ------------------------------activity管理-----------------------// // activity管理:从列表中移除activity public void removeActivity(Activity activity) { activityList.remove(activity); } // activity管理:添加activity到列表 public void addActivity(Activity activity) { activityList.add(activity); } // activity管理:结束所有activity public void finishAllActivity() { for (Activity activity : activityList) { if (null != activity) { activity.finish(); } } } // 结束线程,一般与finishAllActivity()一起使用 // 例如: finishAllActivity;finishProgram(); public void finishProgram() { android.os.Process.killProcess(android.os.Process.myPid()); } }
异常捕获 简单用法介绍:
public class MyApplication extends Application implements Thread.UncaughtExceptionHandler { @Override public void onCreate() { super.onCreate(); //设置Thread Exception Handler Thread.setDefaultUncaughtExceptionHandler(this); } @Override public void uncaughtException(Thread thread, Throwable ex) { System.out.println("uncaughtException"); System.exit(0); Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } }
以上的尝试方法都没有成功,下面的一种方式成功了。
步骤一、在你自己的Application类的onCreate()方法下 加入代码捕获异常,并且处理异常。Thread.setDefaultUncaughtExceptionHandler(restartHandler); // 程序崩溃时触发线程 以下用来捕获程序崩溃异常
@Override public void onCreate() { super.onCreate(); Thread.setDefaultUncaughtExceptionHandler(restartHandler); // 程序崩溃时触发线程 以下用来捕获程序崩溃异常 }
步骤二、 编写方法创建服务用于捕获崩溃异常并且处理
// 创建服务用于捕获崩溃异常 private UncaughtExceptionHandler restartHandler = new UncaughtExceptionHandler() { public void uncaughtException(Thread thread, Throwable ex) { restartApp();//发生崩溃异常时,重启应用 } }; //重启App public void restartApp(){ Intent intent = new Intent(this,MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); this.startActivity(intent); android.os.Process.killProcess(android.os.Process.myPid()); //结束进程之前可以把你程序的注销或者退出代码放在这段代码之前 }
成功解决问题。
0 0
- android 中处理崩溃异常并重启程序出现页面重叠的问题
- 中处理崩溃异常并重启程序
- 中处理崩溃异常并重启程序
- android 中处理崩溃异常并重启程序
- android 中处理崩溃异常并重启程序
- android 中处理崩溃异常并重启程序
- android 中处理崩溃异常并重启程序
- android 中处理崩溃异常并重启程序
- android 中处理崩溃异常并重启程序
- android 中处理崩溃异常并重启程序
- android 中处理崩溃异常并重启程序
- android 中处理崩溃异常并重启程序
- android 中处理崩溃异常并重启程序
- Android UncaughtExceptionHandler 记录异常并重启程序
- 捕获崩溃异常并重启程序,上传崩溃日志到服务器
- Android处理应用崩溃异常并重启应用
- 捕获全局异常并重启程序
- Android中 崩溃异常的处理
- 使用广义表创建二叉树
- 在Eclipse中安装和使用Git Plugin
- nginx https配置后无法访问,可能防火墙在捣鬼
- JDBC之结果集元数据、事务控制、批量执行、返回自动主键
- Git - 在本次commit上再次修改
- android 中处理崩溃异常并重启程序出现页面重叠的问题
- 修改tomcat端口号
- anaconda安装报错解决
- struts2总结
- 利用grub2.0/grub4dos实现双硬盘双(多)系统
- java webstruct2 学习
- android复习路之fragment篇
- tornado学习笔记(一):如何给ioloop.run_sync()中调用的函数传入参数
- Servlet工作原理和生命周期