是否无法在UncaughtExceptionHandler中启动Activity

时间:2015-05-15 09:24:07

标签: android

我发现在UncaughtExceptionHandler中启动新活动时它不起作用。我的意思是不要显示恼人的Android崩溃对话框。另一方面,我想开始一个新的活动来表明用户我们遇到了一个严重的错误,你是否想要退出或继续使用APP仍有可能发生奇怪的事情。

我甚至尝试通过

在UncaughtExceptionHandler中重启APP
final Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());  
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  
    startActivity(intent); 

但是,我再次运气不好。它也不起作用......

4 个答案:

答案 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;
        }
    });
}

}