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

Oreo系统中Dialog主题AppCompatActivity的onCreate()崩溃求助

解决Android Oreo中Dialog主题Activity启动崩溃的问题

我之前也踩过这个一模一样的坑!用@style/Theme.AppCompat.Light.Dialog.NoActionBar作为Activity主题,在Android 7.1及以下版本运行完全正常,但一到Oreo(API 26)就直接崩溃,太头疼了。咱们来一步步搞定它:

问题根源

Android 8.0开始,系统对使用Dialog主题的Activity的窗口属性做了更严格的校验。在Oreo之前,系统会默认给这类Activity设置android:windowIsFloating="true",但从API 26起,这个默认配置被移除了。如果没有显式声明这个属性,系统无法正确初始化窗口,就会抛出WindowManager$BadTokenException(这就是你看到的RuntimeException的底层原因)。

解决方案

方案1:显式设置主题的windowIsFloating属性

这是最直接的修复方式,只需要修改你的主题配置:

  1. 打开res/values/styles.xml,创建一个自定义的Dialog主题,继承原主题并添加android:windowIsFloating属性:
<style name="CustomDialogTheme" parent="Theme.AppCompat.Light.Dialog.NoActionBar">
    <item name="android:windowIsFloating">true</item>
    <!-- 可选:如果需要调整Dialog的大小,可以添加以下属性 -->
    <item name="android:windowMinWidthMajor">85%</item>
    <item name="android:windowMinWidthMinor">85%</item>
</style>
  1. 在AndroidManifest.xml中,把AdvancePaintActivity的主题替换成这个自定义主题:
<activity
    android:name=".AdvancePaintActivity"
    android:theme="@style/CustomDialogTheme"
    android:screenOrientation="portrait"/>

方案2:改用DialogFragment实现Dialog效果

这是Google推荐的更优雅的方式,不仅能避免版本兼容问题,还能更好地处理生命周期(比如屏幕旋转)。示例代码如下:
首先创建一个DialogFragment类:

public class AdvancePaintDialogFragment extends DialogFragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // 隐藏Dialog标题
        getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
        // 加载你的布局
        return inflater.inflate(R.layout.activity_paint_advance, container, false);
    }

    @Override
    public void onResume() {
        super.onResume();
        // 自定义Dialog的窗口大小(可选)
        Window window = getDialog().getWindow();
        if (window != null) {
            WindowManager.LayoutParams params = window.getAttributes();
            params.width = WindowManager.LayoutParams.MATCH_PARENT;
            params.height = WindowManager.LayoutParams.WRAP_CONTENT;
            window.setAttributes(params);
        }
    }
}

然后在需要启动这个Dialog的地方调用:

new AdvancePaintDialogFragment().show(getSupportFragmentManager(), "AdvancePaintDialog");

方案3:改用普通Activity主题+自定义布局模拟Dialog

如果你的"Dialog样式Activity"其实需要全屏展示,不如直接用普通的Theme.AppCompat.Light.NoActionBar主题,然后在布局中添加一个模拟Dialog的容器(比如圆角背景、居中的LinearLayout),这样完全不会有版本兼容问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:18:25