我在Activity的onCreate()为当前线程设置了一个默认的UncaughtExceptionHandler ,并从AlertDialog的onClick()侦听器中抛出了一个AlertDialog但是这个异常没有被捕获。 我还尝试从onCreateOptionsMenu()和onOptionsItemSelected()抛出异常并且没有捕获它。 但是,当它从onCreate()或onResume()引发时会被捕获。
这是我的活动:
public class MainActivity extends AppCompatActivity implements DialogInterface.OnClickListener { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Thread.setDefaultUncaughtExceptionHandler(new DefExcHandler()); Log.d(TAG, "onCreate: "+Thread.currentThread().getName()+" "+Thread.currentThread().getId()); AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setNeutralButton("CRASH", this); AlertDialog dialog = builder.create(); dialog.show(); dialog.setCancelable(false); dialog.setCanceledOnTouchOutside(false); } @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); Log.d(TAG, "onClick: "+Thread.currentThread().getName()+" "+Thread.currentThread().getId()); throw new RuntimeException(); } }这里是我的异常处理程序:
public class DefExcHandler implements Thread.UncaughtExceptionHandler { private static final String TAG = "DefExcHandler"; public DefExcHandler() { Log.d(TAG, "DefaultExceptionHandler: "); } @Override public void uncaughtException(Thread thread, Throwable ex) { Log.d(TAG, "Uncaught exception caught: "+ex.getMessage()+" "+ex.getCause().toString()); } }基于我在活动中创建的日志消息,在onCreate()和onClick() ,线程是相同的:
09-27 15:00:57.260 10667-10667/a.b.c D/MainActivity: onCreate: main 1 09-27 15:01:52.680 10667-10667/a.b.c D/MainActivity: onClick: main 1为什么从onClick() , onCreateOptionsMenu()或onOptionsItemSelected()抛出异常时没有捕获到异常?
I set a default UncaughtExceptionHandler for the current thread in my Activity's onCreate() and throw a RunTimeException from my AlertDialog's onClick() listener but the exception is not caught. I also tried throwing the exception from onCreateOptionsMenu() and onOptionsItemSelected() and it wasn't caught. It is caught however when thrown from onCreate() or onResume().
Here's my activity:
public class MainActivity extends AppCompatActivity implements DialogInterface.OnClickListener { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Thread.setDefaultUncaughtExceptionHandler(new DefExcHandler()); Log.d(TAG, "onCreate: "+Thread.currentThread().getName()+" "+Thread.currentThread().getId()); AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setNeutralButton("CRASH", this); AlertDialog dialog = builder.create(); dialog.show(); dialog.setCancelable(false); dialog.setCanceledOnTouchOutside(false); } @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); Log.d(TAG, "onClick: "+Thread.currentThread().getName()+" "+Thread.currentThread().getId()); throw new RuntimeException(); } }And here's my exception handler:
public class DefExcHandler implements Thread.UncaughtExceptionHandler { private static final String TAG = "DefExcHandler"; public DefExcHandler() { Log.d(TAG, "DefaultExceptionHandler: "); } @Override public void uncaughtException(Thread thread, Throwable ex) { Log.d(TAG, "Uncaught exception caught: "+ex.getMessage()+" "+ex.getCause().toString()); } }Based on the log messages I make in my activity the thread is the same when in onCreate() and onClick():
09-27 15:00:57.260 10667-10667/a.b.c D/MainActivity: onCreate: main 1 09-27 15:01:52.680 10667-10667/a.b.c D/MainActivity: onClick: main 1Why is the exception not caught when thrown from onClick(), onCreateOptionsMenu() or onOptionsItemSelected()?
最满意答案
我试图重现应用程序的行为。 似乎错过了DefExcHandler实例,因为它没有记录任何内容,但我尝试了另外两个有效的方法:断点和文件创建。
请尝试在uncaughtException()设置断点。 我相信它会停止代码中的执行。 我在下面编写了一个示例,它使用一个文件作为标志来指示实际上正在调用未捕获的异常处理程序。
总而言之,似乎正在调用DefExcHandler.uncaughtException() ,但Android无法通过某种未知原因进行日志记录,可能是内部竞争条件。
// Example that assures that an UncaughtExceptionHandler // is being invoked by flagging execution with file creation. public class MainActivity extends ... implements ... { private File mCrashFile; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mCrashFile = new File(getFilesDir(), "crash"); // Crash file existence means the application has crashed before. Log.d(TAG, "crash file exists: " + mCrashFile.exists()); // Clear crash flag. if (mCrashFile.exists()) { Log.d(TAG, "crash file delete: " + mCrashFile.delete()); } Thread.setDefaultUncaughtExceptionHandler(new DefExcHandler()); ... } private class DefExcHandler implements Thread.UncaughtExceptionHandler { @Override public void uncaughtException(Thread thread, Throwable ex) { // Set crash flag. try { mCrashFile.createNewFile(); } catch (IOException e) { // dunno if it really prints anything e.printStackTrace(); } } } }I tried to reproduce the application's behavior. The DefExcHandler instance seems to be missed since it isn't logging anything, but I tried two other things that worked: breakpoint and file creation.
Please try to set a breakpoint inside uncaughtException(). I believe it will stop the execution in your code. And I have written an example below that uses a file as a flag to indicate that the uncaught exception handler is really being invoked.
In sum, it seems that DefExcHandler.uncaughtException() is being called but Android can't do the logging for some unknown reason, maybe an internal race condition.
// Example that assures that an UncaughtExceptionHandler // is being invoked by flagging execution with file creation. public class MainActivity extends ... implements ... { private File mCrashFile; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mCrashFile = new File(getFilesDir(), "crash"); // Crash file existence means the application has crashed before. Log.d(TAG, "crash file exists: " + mCrashFile.exists()); // Clear crash flag. if (mCrashFile.exists()) { Log.d(TAG, "crash file delete: " + mCrashFile.delete()); } Thread.setDefaultUncaughtExceptionHandler(new DefExcHandler()); ... } private class DefExcHandler implements Thread.UncaughtExceptionHandler { @Override public void uncaughtException(Thread thread, Throwable ex) { // Set crash flag. try { mCrashFile.createNewFile(); } catch (IOException e) { // dunno if it really prints anything e.printStackTrace(); } } } }
更多推荐
发布评论