【转】Android 中处理崩溃异常并重启程序出现页面重叠的问题
原文地址:http://blog.csdn.net/jiang547860818/article/details/53641113
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;
}
}
- 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
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
二、通过在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());
}
}
- 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
人为的制造一个异常
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();
}
}
- 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
<?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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
尝试二:
通用 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());
}
}
- 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
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
异常捕获 简单用法介绍:
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);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
以上的尝试方法都没有成功,下面的一种方式成功了。
步骤一、在你自己的Application类的onCreate()方法下 加入代码捕获异常,并且处理异常。Thread.setDefaultUncaughtExceptionHandler(restartHandler); // 程序崩溃时触发线程 以下用来捕获程序崩溃异常
@Override
public void onCreate() {
super.onCreate();
Thread.setDefaultUncaughtExceptionHandler(restartHandler); // 程序崩溃时触发线程 以下用来捕获程序崩溃异常
}
- 1
- 2
- 3
- 4
- 5
步骤二、 编写方法创建服务用于捕获崩溃异常并且处理
// 创建服务用于捕获崩溃异常
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()); //结束进程之前可以把你程序的注销或者退出代码放在这段代码之前
}
【转】Android 中处理崩溃异常并重启程序出现页面重叠的问题的更多相关文章
- Android中处理崩溃异常和记录日志(转)
现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不定就出现崩溃的现象,开发者个人不可能购买所有设备逐个调试,所以在程序发布出去之后,如果出现了崩溃现象,开 ...
- Android中处理崩溃异常
转自:http://my.eoe.cn/817027/archive/17997.html 大家都知道,现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不 ...
- Android中处理崩溃异常和记录日志
大家都知道,现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不定就出现崩溃的现象,开发者个人不可能购买所有设备逐个调试,所以在程序发布出去之后,如果出现了 ...
- Android中处理崩溃异常CrashHandler
来源:http://blog.csdn.net/liuhe688/article/details/6584143 大家都知道,现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程 ...
- 【转】Android中处理崩溃异常
大家都知道,现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不定就出现崩溃的现象,开发者个人不可能购买所有设备逐个调试,所以在程序发布出去之后,如果出现了 ...
- Android中处理崩溃异常 (转)
大家都知道,现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不定就出现崩溃的现象,开发者个人不可能购买所有设备逐个调试,所以在程序发布出去之后,如果出现了 ...
- 【Android实战】Android中处理崩溃异常
public class MainActivity extends ActionBarActivity { public CrashApplication application; @Override ...
- Android中处理崩溃闪退错误
Android中处理崩溃闪退异常 大家都知道,现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不定就出现崩溃的现象,开发者个人不可能购买所有设备逐个调试, ...
- Android application捕获崩溃异常
Java代码 .收集所有 avtivity 用于彻底退出应用 .捕获崩溃异常,保存错误日志,并重启应用 , intent, , restartIntent); // 关闭当前应用 finishAllA ...
随机推荐
- python最重要的模块logging
logging模块 这个模块是目前最重要的模块!!!我一定给讲透彻一点 很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python中的loggi ...
- 如何定位BAD_ACCESS
1.访问了野指针,比如对一个已经释放的对象执行了release.访问已经释放对象的成员变量或者发消息. 死循环 如何调试BAD_ACCESS错误 1.重写object的respondsToSelect ...
- CSS Div固定在网页顶部、底部、左侧、右侧
Div固定在网页顶部 .header { width:100%; height:80px; background-color:#FAFAFA; position:fixed; top:; left:; ...
- HDU2896 病毒侵袭 【AC自动机】
HDU2896 病毒侵袭 Problem Description 当太阳的光辉逐渐被月亮遮蔽,世界失去了光明,大地迎来最黑暗的时刻....在这样的时刻,人们却异常兴奋--我们能在有生之年看到500年一 ...
- java获取服务器的ip和地址
HttpServletRequest httpRequest=(HttpServletRequest)request; String strBackUrl = "http://" ...
- Javascript 严格模式下保留关键字
为了应对未来的版本,以下关键字在严格模式下禁止使用. implements interface let package private protected public static yield 示例 ...
- python socket的应用 以及tcp中的粘包现象
1,socket套接字 一个接口模块,在tcp/udp协议之间的传输接口,将其影藏在socket之后,用户看到的是socket让其看到的. 在tcp中当做server和client的主要模块运用 #s ...
- Android照片墙完整版,完美结合LruCache和DiskLruCache
转载地址:http://blog.csdn.net/guolin_blog/article/details/34093441#comments 在上一篇文章当中,我们学习了DiskLruCache的概 ...
- Java语言与C语言混合编程(2)--在Java中调用C语言本地库
在上一篇文章中介绍了Java语言中的native关键字,以及Java语言调用C语言的编译生成本地动态链接库(DLL)实现加法运算的小例子,本文通过一个更加详细的例子,深入讲解Java语言调用C语言的函 ...
- Magento(麦进斗)安装问题
安装到数据库那一步会跳出 lib\Zend\Db\Statement\Pdo.php on line 228 错误 解决方案: 在你的php模块里的php.ini文件添加(或者修改)max_execu ...