在 `Thread.setDefaultUncaughtExceptionHandler` 中显示一个对话框

2024-01-02

当我的 Android 应用程序抛出异常时,我想显示一个自定义对话框来告诉用户发生了错误,所以我使用Thread.setDefaultUncaughtExceptionHandler设置全局异常处理程序:

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread thread, final Throwable ex) {
                AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
                builder.setTitle("There is something wrong")
                        .setMessage("Application will exit:" + ex.toString())
                        .setPositiveButton("OK", new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                // throw it again
                                throw (RuntimeException) ex;
                            }
                        })
                        .show();
            }
        });
    }

}

但我发现有任何异常抛出,AlertDialog不会显示,相反,应用程序会阻塞,一段时间后,它将显示一个系统对话框:

X app is not responding. Would you like to close it?
Wait  |  OK

我现在应该怎么做?


UPDATE

The log:

11-16 12:54:16.017: WARN/WindowManager(90): Attempted to add window with non-application token WindowToken{b38bb6a8 token=null}.  Aborting.

看来错误来自new AlertDialog.Builder(getApplicationContext());

但这是一个异常处理程序Application子类,如何为其设置活动实例?


您无法从此处执行任何 UI 操作。只需启动另一个活动/启动屏幕即可。传递一个额外的意图来表示崩溃并在该活动中显示对话框。

    /*
     * (non-Javadoc)
     * 
     * @see
     * java.lang.Thread.UncaughtExceptionHandler#uncaughtException(java.
     * lang.Thread, java.lang.Throwable)
     */
    @Override
    public void uncaughtException(Thread t, final Throwable e) {
        StackTraceElement[] arr = e.getStackTrace();
        final StringBuffer report = new StringBuffer(e.toString());
        final String lineSeperator = "-------------------------------\n\n";
        report.append(DOUBLE_LINE_SEP);
        report.append("--------- Stack trace ---------\n\n");
        for (int i = 0; i < arr.length; i++) {
            report.append( "    ");
            report.append(arr[i].toString());
            report.append(SINGLE_LINE_SEP);
        }
        report.append(lineSeperator);
        // If the exception was thrown in a background thread inside
        // AsyncTask, then the actual exception can be found with getCause
        report.append("--------- Cause ---------\n\n");
        Throwable cause = e.getCause();
        if (cause != null) {
            report.append(cause.toString());
            report.append(DOUBLE_LINE_SEP);
            arr = cause.getStackTrace();
            for (int i = 0; i < arr.length; i++) {
                report.append("    ");
                report.append(arr[i].toString());
                report.append(SINGLE_LINE_SEP);
            }
        }
        // Getting the Device brand,model and sdk verion details.
        report.append(lineSeperator);
        report.append("--------- Device ---------\n\n");
        report.append("Brand: ");
        report.append(Build.BRAND);
        report.append(SINGLE_LINE_SEP);
        report.append("Device: ");
        report.append(Build.DEVICE);
        report.append(SINGLE_LINE_SEP);
        report.append("Model: ");
        report.append(Build.MODEL);
        report.append(SINGLE_LINE_SEP);
        report.append("Id: ");
        report.append(Build.ID);
        report.append(SINGLE_LINE_SEP);
        report.append("Product: ");
        report.append(Build.PRODUCT);
        report.append(SINGLE_LINE_SEP);
        report.append(lineSeperator);
        report.append("--------- Firmware ---------\n\n");
        report.append("SDK: ");
        report.append(Build.VERSION.SDK);
        report.append(SINGLE_LINE_SEP);
        report.append("Release: ");
        report.append(Build.VERSION.RELEASE);
        report.append(SINGLE_LINE_SEP);
        report.append("Incremental: ");
        report.append(Build.VERSION.INCREMENTAL);
        report.append(SINGLE_LINE_SEP);
        report.append(lineSeperator);

        Log.e("Report ::", report.toString());
        Intent crashedIntent = new Intent(BaseActivity.this, SplashActivity.class);
        crashedIntent.putExtra(EXTRA_CRASHED_FLAG,  "Unexpected Error occurred.");
        crashedIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
        crashedIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(crashedIntent);

        System.exit(0);
        // If you don't kill the VM here the app goes into limbo

    }

另请参阅:

实例化 AlertDialog 的 Android UncaughtExceptionHandler 中断 https://stackoverflow.com/questions/5519347/android-uncaughtexceptionhandler-that-instantiates-an-alertdialog-breaks

Toast 未显示在 UnCaughtExceptionHandler 中 https://stackoverflow.com/questions/11609640/toast-not-showing-up-in-uncaughtexceptionhandler

如果主线程崩溃,如何从 UncaughtExceptionHandler 启动活动? https://stackoverflow.com/questions/2222396/how-to-start-activity-from-uncaughtexceptionhandler-if-this-is-main-thread-crash

我是怎么做的:

我有一个扩展 Activity 的 BaseActivity,在活动的 onCreate 中我设置了 UncaughtExceptionHandler。我的所有活动都扩展了 BaseActivity 而不是 Activity。

Keys

  1. 您不能在中设置异常处理程序Application.onCreate,相反,您应该创建一个BaseActivity并将其设置在onCreate它的方法。
  2. 启动 SplashActivity 后,我们应该调用System.exit(0)
  3. 我们无法保存错误实例以将其共享给SplashActivity,因为它会被销毁,所以我们可以传递一些错误消息或将其保留在文件中。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 `Thread.setDefaultUncaughtExceptionHandler` 中显示一个对话框 的相关文章

随机推荐

  • WinRT 从视频流中提取帧

    我正在使用内置摄像头解码条形码 我使用capElement Source CapturePhotoToStreamAsync从预览中捕获照片 它可以工作 但会冻结应用程序一小会儿 这感觉非常笨拙和错误 因此 我希望在后台执行此操作 同时在处
  • DropDownList如何选择默认值

    我的页面上有很多 DropDownList class BigViewModel public List
  • Android TextInputLayout/EditText 不是全尺寸并截断文本

    我有一个包含计算器的片段 只有三个监听输入的 TextInputEditTexts 这些输入在相对布局中设置 如下所示
  • Node.js 与其他 Web 技术相比的优势 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • scikit learn 中的特殊性

    I need specificity对于我的分类 其定义为 TN TN FP 我正在编写一个自定义记分器函数 from sklearn metrics import make scorer def specificity loss func
  • libtool 与 ar 用于创建静态库(xcode 链接器)

    在 Mac 10 5 上使用 xcode 通过 libtool 创建静态库和通过命令行使用 ar 都会生成一个 libMainProject a 文件 但是 当尝试使用 libtool 生成的文件链接到 xcode 应用程序时 我最终会收到
  • 带星号的批量 FOR 循环

    我有这个单行 CMD 文件 TEST CMD for f in 1 2 3 4 5 6 7 8 DO ECHO f 如果我运行这个 TEST this is a test 它正确地在单独的行上回显每个参数 即 this is a test
  • 渲染良好的网络字体解决方案

    挑战 提供动态网页字体 可在所有主要浏览器 设备和操作系统上呈现可接受的效果 故事 所以我过去使用过 cufon 或 sifr 后来放弃了这两种方式 转而使用 font face 在生产中使用 font face一段时间后 我有了一个可怕的
  • 如何解决读取图像文件时IOError:损坏的数据流?

    我在 Ubuntu 11 04 下工作 我正在尝试在我的 Django 项目中使用 PIL 遗憾的是 PIL 无法加载我的图像 以下是 PIL 设置摘要 PIL 1 1 7 SETUP SUMMARY version 1 1 7 platf
  • 为什么Java char原语占用2字节内存?

    Java char 原始数据类型是 2 个字节 而 C 是 1 个字节 有什么原因吗 Thanks Java 最初设计时 预计任何 Unicode 字符都可以容纳 2 个字节 16 位 因此char and Character进行了相应的设
  • 带有 Tibco Native Libs 的 Java Webstart

    我正在尝试部署一个使用nativeTibrv 的实施通过TibrvJ图书馆使用Java 网络启动 我已经把所有的Windows都打包了dlls从内部c tibco tibrv bin放入 Jar 文件并将它们添加到nativelib中的元素
  • 在 XML/XSLT 中转义美元符号

    我正在处理使用 XSLT 转换 XML 来自遗留系统 的要求 我在处理带有美元符号的标签时遇到了问题 这就是它们在遗留系统中存储和生成的方式 示例 XML 文件的示例
  • 在 Jest 中使用 Next.Js 测试 Api

    我想使用 Jest 为我的 Api 文件编写测试用例 它使用 Next js 我尝试了很多方法 但无法获得任何文件覆盖率 ApiFile js const axios require axios import getConfig from
  • 使用 video.js 包装器启用 YouTube 播放

    好的 所以我正在尝试使用 video js 项目包装 换肤 YouTube 视频 以实现与我网站上其他视频类似的外观和感觉 现在根据您可以看到的文档here https github com videojs video js blob ma
  • Django 1.3 日志记录:未记录 500 个错误

    我正在努力让 django request 记录器按照广告宣传的方式工作 500 个错误似乎不会传播到附加到它的处理程序 在每个新项目的默认日志记录配置中 注释表示 此配置执行的日志记录是针对每个 HTTP 500 错误向站点管理员发送电子
  • phpDoc 表示法指定返回类型与参数类型相同

    想象一下以下假设的类结构 在所有 PHPdoc 提示都正确设置的情况下 这并不是一个非常罕见的场景 class BaseFilter base methods class TextFilter extends BaseFilter publ
  • 如何使用git将本地存储库复制到远程服务器?

    我正在尝试使用 git 在远程服务器中部署本地代码 这就是我所做的local文件夹我的网站 git init git add git commit m Initial commit 然后 在我的网络服务器 mkdir public html
  • jQuery 选择具有特定标题的表格单元格

    我有一个带有 标题 的表 该表使用常规 tr 标签 不是 th 我需要找到标题 Col2 然后为 Col2 下的每个单元格添加一个锚点 我可以 td contains Col2 查找标题 但数据行也可能有 Col2 我如何仅搜索第一行 然后
  • 将 robomongo 连接到 mongoDB docker 容器

    我正在运行一个NodeJS应用程序与docker 撰写 https docs docker com compose 一切正常 我可以通过连接到容器内的 Mongo 来查看所有数据 但是当我连接到机器人蒙戈 https robomongo o
  • 在 `Thread.setDefaultUncaughtExceptionHandler` 中显示一个对话框

    当我的 Android 应用程序抛出异常时 我想显示一个自定义对话框来告诉用户发生了错误 所以我使用Thread setDefaultUncaughtExceptionHandler设置全局异常处理程序 public class MyApp