这是@SilentKnight s 版本的改进版
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;
}
});
}
}