You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UncaughtExceptionHandler无法启动Activity问题求助

问题:UncaughtExceptionHandler无法启动异常处理Activity

自定义了继承自android.app.Application的类,设置全局未捕获异常处理器,期望触发异常时启动指定的RuntimeException Activity,但始终无法成功。以下是相关代码与配置:

自定义Application类

public final class Application extends android.app.Application {
    public Application() {
        Thread.setDefaultUncaughtExceptionHandler(new Application.UncaughtExceptionHandler());
    }
    static Context context;

    static final class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
        @Override
        public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
            context.startActivity(new Intent()
                            .setClass(context, RuntimeException.class)
                            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                            /*.putExtra("u", true).putExtra("e", e)*/);
            //System.exit(0);
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
    }
}

RuntimeException Activity类(已在清单注册)

public class RuntimeException extends Activity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.a_exception);

        Bundle extras = getIntent().getExtras();
        boolean uncaught = extras.getBoolean("u", false);
        Throwable exception = (Throwable) extras.get("e");

        String exceptionType;
        if (uncaught) exceptionType = "Uncaught exception:\n"; else exceptionType = "Exception:\n";

        TextView msg = findViewById(R.id.ex_msg);
        msg.setText(exceptionType + exception.getLocalizedMessage());
    }
}

AndroidManifest.xml配置

<application
        android:name=".application.Application"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyTheme"
        tools:targetApi="31">
        <activity
            android:name=".activity.Launcher"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".activity.FileList"/>
        <activity android:name=".activity.RuntimeException"/>
    </application>

解决方案

1. 修正异常处理器初始化时机

不要在Application构造方法中设置异常处理器,此时context尚未初始化,会导致后续启动Activity时出现空指针异常。将处理器初始化移到onCreate()方法中:

@Override
public void onCreate() {
    super.onCreate();
    context = getApplicationContext();
    // 移至此处设置全局异常处理器
    Thread.setDefaultUncaughtExceptionHandler(new Application.UncaughtExceptionHandler());
}

2. 完善异常处理逻辑,确保Activity正常启动

自定义处理器中需保证Activity启动逻辑执行完成后再终止进程,同时添加栈清理标记避免页面混乱:

static final class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
    private Thread.UncaughtExceptionHandler defaultHandler;

    public UncaughtExceptionHandler() {
        defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
    }

    @Override
    public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
        try {
            Intent intent = new Intent(context, RuntimeException.class);
            // 添加CLEAR_TASK标记,确保异常Activity成为栈中唯一页面
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            context.startActivity(intent);
            // 延迟1秒,给Activity启动留足时间
            Thread.sleep(1000);
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            // 调用系统默认处理器或直接终止进程
            if (defaultHandler != null) {
                defaultHandler.uncaughtException(t, e);
            } else {
                android.os.Process.killProcess(android.os.Process.myPid());
                System.exit(1);
            }
        }
    }
}

3. 修复异常对象传递问题

Throwable直接通过putExtra传递可能存在序列化失败风险,建议转为字符串传递:

// 在异常处理器中传递异常堆栈信息
intent.putExtra("u", true);
intent.putExtra("exception_msg", Log.getStackTraceString(e));

在RuntimeException Activity中接收:

String exceptionMsg = getIntent().getStringExtra("exception_msg");
msg.setText(exceptionType + exceptionMsg);

4. 避免类名冲突

当前Activity类名RuntimeException与Java自带的java.lang.RuntimeException重名,可能导致类加载混淆,建议重命名为ExceptionHandlerActivity,同时同步修改清单文件和Intent中的类引用。

内容的提问来源于stack exchange,提问作者na29

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 02:52:46