我发现在UncaughtExceptionHandler中启动新活动时它不起作用。我的意思是不要显示恼人的Android崩溃对话框。另一方面,我想开始一个新的活动来表明用户我们遇到了一个严重的错误,你是否想要退出或继续使用APP仍有可能发生奇怪的事情。
我甚至尝试通过
在UncaughtExceptionHandler中重启APPfinal Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
但是,我再次运气不好。它也不起作用......
答案 0 :(得分:2)
我试图在崩溃发生后重启我的应用程序。我在Application扩展类中捕获了所有未捕获的异常。在异常处理程序中执行有关异常的操作并尝试设置AlarmManager以重新启动我的应用程序。这是我在我的应用程序中如何执行此操作的示例,但我只将异常记录到数据库。
public class MyApplication extends Application {
// uncaught exception handler variable
private UncaughtExceptionHandler defaultUEH;
// handler listener
private Thread.UncaughtExceptionHandler _unCaughtExceptionHandler =
new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
// here I do logging of exception to a db
PendingIntent myActivity = PendingIntent.getActivity(getContext(),
192837, new Intent(getContext(), MyActivity.class),
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager;
alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
15000, myActivity );
System.exit(2);
// re-throw critical exception further to the os (important)
defaultUEH.uncaughtException(thread, ex);
}
};
public MyApplication() {
defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
// setup handler for uncaught exception
Thread.setDefaultUncaughtExceptionHandler(_unCaughtExceptionHandler);
}
}
答案 1 :(得分:0)
您可以使用PendingIntent
启动AlarmManager
。
AlarmManager alarm = (AlarmManager) context.getSystemService(Activity.ALARM_SERVICE);
PendingIntent pi = PendingIntent.getActivity(context, 12345, new Intent(context,
startActivity).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK),
PendingIntent.FLAG_ONE_SHOT);
alarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 0, pi);
将context
变量的值放在实现的构造函数中。
答案 2 :(得分:0)
你可以使用(延迟后)一个帖子。
编辑:或Thread.sleep
@Override
public void uncaughtException(Thread t, Throwable e) {
this.ex = e;
try {
new Thread() {
@Override
public void run() {
Looper.prepare();
String className = am.getRunningTasks(1).get(0).topActivity
.getClassName
Toast.makeText(context,
context.getString(R.string.uncaught_exception),
Constants.ToastDuration).show();
Looper.loop();
}
}.start();
Thread.sleep(1000);
Intent errorIntent = new Intent(context.getApplicationContext(),
LoginActivity.class);
errorIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK
| Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(errorIntent);
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1); //OPTIONAL and not suggested not to be followed
} catch (InterruptedException exc) {
CommonUtil.logMessage(LOG,(Exception) exc);
} catch (Exception ex) {
CommonUtil.logMessage(LOG,(Exception) ex);
}
}
答案 3 :(得分:0)
这是@SilentKnight的版本的改进版本
public class MyApplication extends Application {
// uncaught exception handler variable
private Thread.UncaughtExceptionHandler defaultUEH;
// handler listener
private Thread.UncaughtExceptionHandler _unCaughtExceptionHandler =
new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
//get stack trace
//get error stacktrace
String _OSVERSION = System.getProperty("os.version");
String _RELEASE = android.os.Build.VERSION.RELEASE;
String _DEVICE = android.os.Build.DEVICE;
String _MODEL = android.os.Build.MODEL;
String _PRODUCT = android.os.Build.PRODUCT;
String _BRAND = android.os.Build.BRAND;
String _DISPLAY = android.os.Build.DISPLAY;
String _CPU_ABI = android.os.Build.CPU_ABI;
String _CPU_ABI2 = android.os.Build.CPU_ABI2;
String _UNKNOWN = android.os.Build.UNKNOWN;
String _HARDWARE = android.os.Build.HARDWARE;
String _ID = android.os.Build.ID;
String _MANUFACTURER = android.os.Build.MANUFACTURER;
String _SERIAL = android.os.Build.SERIAL;
String _USER = android.os.Build.USER;
String _HOST = android.os.Build.HOST;
String all = String.format("os:%s\nrelease:%s\ndev:%s\nmodel:%s\nprod:%s\nbrand:%s\ndisp:%s\ncpu_abi:%s\n" +
"cpu_abi2:%s\nunknown:%s\nhardware:%s\nid:%s\nmanu:%s\nserial:%s\nhost:%s\nuser:%s\n",
_OSVERSION, _RELEASE, _DEVICE, _MODEL, _PRODUCT, _BRAND, _DISPLAY, _CPU_ABI,
_CPU_ABI2, _UNKNOWN, _HARDWARE, _ID, _MANUFACTURER, _SERIAL, _HOST, _USER);
long time = System.currentTimeMillis();
String st = String.format("Process down\nTime: %s [%s]\n\nDev infos:\n%s\nStacktraces...\n\n", convertTime(time), time, all);
for(StackTraceElement e : ex.getStackTrace())
st += "\n" + String.format("%s> %s (=%s); [%s]; {%s}", e.getLineNumber(), e.getClassName(), e.getFileName(), e.getMethodName(), e.isNativeMethod());
//and write it to file
FileManager.getInstance(getApplicationContext(), String.format("logs/%s.str", time)).write(st);
//create the intent
Intent intent = new Intent(getApplicationContext(), Killed.class);
intent.putExtra("log", st);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
// here I do logging of exception to a db
PendingIntent myActivity = PendingIntent.getActivity(getApplicationContext(),
192837, intent,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager;
alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
15000, myActivity);
System.exit(2);
// re-throw critical exception further to the os (important)
defaultUEH.uncaughtException(thread, ex);
}
};
public String convertTime(long time){
Date date = new Date(time);
Format format = new SimpleDateFormat("yyyy MM dd HH:mm:ss");
return format.format(date);
}
public MyApplication() {
defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
// setup handler for uncaught exception
Thread.setDefaultUncaughtExceptionHandler(_unCaughtExceptionHandler);
}
}
另一个有用的课程可能是淋浴:
public class Killed extends LActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
HorizontalScrollView hsv = new HorizontalScrollView(this);
ScrollView sv = new ScrollView(this);
hsv.addView(sv);
sv.addView(tv);
setContentView(hsv);
final String log = getIntent().getStringExtra("log");
tv.setText(log);
tv.setTextIsSelectable(true);
tv.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
"mailto","developer@gmail.com", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Error log: MyApp");
emailIntent.putExtra(Intent.EXTRA_TEXT, log);
startActivity(Intent.createChooser(emailIntent, "Send email..."));
return true;
}
});
}
}