【问题标题】:"android.util.AndroidRuntimeException: requestFeature() must be called before adding content" on showDialog(dialogId)“android.util.AndroidRuntimeException:在添加内容之前必须调用 requestFeature()”在 showDialog(dialogId)
【发布时间】:2011-01-28 08:55:23
【问题描述】:

这件事把我逼到了精神错乱的边缘!

我有一个使用 onClickListener 初始化 Button 视图的活动,如下所示:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.myLayout);

    mMyButton = (Button) findViewById(R.id.myButtonId);
    mMyButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            showDialog(ID_MYDIALOG);
        }
    });
}

我还编写了自己的对话框构建器类(单例),因为我的应用程序中有几个其他 Activity,它们将使用一组通用对话框,因此在给定 Activity 的 onCreateDialog(int id) 函数中我调用:

@Override
protected Dialog onCreateDialog(int id) {
    Dialog dialog;

    switch (id) {
        case ID_MYDIALOG:
            dialog = DialogBuilder.getInstance().getMyDialog(this, mUri, mListener);
            break;

        default:
            dialog = null;
            break;
    }

    return dialog;
}

mUrimListener 变量在别处定义,我已验证它们是有效的。单例DialogBuilder 类的相关部分如下所示:

public AlertDialog getMyDialog(Context context, Uri uri, DialogInterface.OnClickListener listener) {
    // Inflate the custom body for the AlertDialog.
    LayoutInflater layoutInflater = LayoutInflater.from(context);
    View view = layoutInflater.inflate(R.layout.myDialogBody, null);

    // Get the data to show in the dialog.
    Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
    cursor.moveToFirst();

    // Create a suitable data adapter and use it to populate the dialog body with data.
    MyDialogDataAdapter adapter = new MyDialogDataAdapter(context, cursor);

    // Populate the GridView in the dialog body with data.
    GridView grid = (GridView) view.findViewById(R.id.myDialogDataGrid);
    grid.setAdapter(adapter);

    return new AlertDialog.Builder(context)
    .setIcon(R.drawable.myDialogIcon)
    .setTitle(R.string.myDialogTitle)
    .setView(view)
    .setPositiveButton(R.string.myDialogDone, listener)
    .create();
}

现在,当我运行我的应用程序并点击按钮(即mMyButton)时,我得到以下异常堆栈跟踪:

E/AndroidRuntime( 1247): FATAL EXCEPTION: main
E/AndroidRuntime( 1247): android.util.AndroidRuntimeException: requestFeature() must be called before adding content
E/AndroidRuntime( 1247):    at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:181)
E/AndroidRuntime( 1247):    at com.android.internal.app.AlertController.installContent(AlertController.java:203)
E/AndroidRuntime( 1247):    at android.app.AlertDialog.onCreate(AlertDialog.java:251)
E/AndroidRuntime( 1247):    at android.app.Dialog.dispatchOnCreate(Dialog.java:307)
E/AndroidRuntime( 1247):    at android.app.Activity.createDialog(Activity.java:886)
E/AndroidRuntime( 1247):    at android.app.Activity.showDialog(Activity.java:2557)
E/AndroidRuntime( 1247):    at android.app.Activity.showDialog(Activity.java:2524)
E/AndroidRuntime( 1247):    at com.dbm.myApp.myActivity$4.onClick(myActivity.java:266)
E/AndroidRuntime( 1247):    at android.view.View.performClick(View.java:2534)
E/AndroidRuntime( 1247):    at android.view.View$PerformClick.run(View.java:9210)
E/AndroidRuntime( 1247):    at android.os.Handler.handleCallback(Handler.java:587)
E/AndroidRuntime( 1247):    at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime( 1247):    at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 1247):    at android.app.ActivityThread.main(ActivityThread.java:3652)
E/AndroidRuntime( 1247):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 1247):    at java.lang.reflect.Method.invoke(Method.java:507)
E/AndroidRuntime( 1247):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
E/AndroidRuntime( 1247):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
E/AndroidRuntime( 1247):    at dalvik.system.NativeStart.main(Native Method)
W/ActivityManager(  212):   Force finishing activity com.dbm.myApp/.myActivity

如果我正确解释堆栈跟踪,则在我点击按钮的那一刻触发问题(截至com.dbm.myApp.myActivity$4.onClick(myActivity.java:266),这是确切的showDialog(ID_MYDIALOG); 行)。

Android 开发者同胞们怎么说?你认为是什么导致了我的问题?

根据编译和单元测试等,假设上述代码是有效的是公平的。但是,给定的代码被简化和剥离以适应论坛,因此,请不要努力评论命名公约等。

【问题讨论】:

  • 我遇到过这个问题,但我不记得确切的解决方法了 :-( 你需要打电话给:requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); 在你的 DialogBu​​ilder 课程中吗?
  • 一个很好的提示,我刚刚测试过,但不幸的是问题仍然存在。此外,我可能需要阅读一些有关 requestFeature() 函数(或快捷版本:requestWindowFeature())以及它们对我的应用程序的实际作用。
  • 我现在已经测试了注释掉单例 DialogBuilder 类中 getMyDialog 函数中的所有内容,并且仍然存在同样的问题。我开始认为我的 Activity 没有正确初始化。

标签: android android-alertdialog


【解决方案1】:

我想我可能已经解决了这个问题:如果我出于某种原因创建 AlertDialog:

return new AlertDialog.Builder(context)
    .setIcon(R.drawable.myDialogIcon)
    .setTitle(R.string.myDialogTitle)
    .setView(view)
    .setPositiveButton(R.string.myDialogDone, listener)
    .show();

即使用 .show(); 而不是 .create(); 问题不再存在。我不知道为什么会这样,或者 AlertDialog.Builder::show() 函数与 AlertDialog.Builder::create(); 函数有什么不同(不仅仅是各个函数名称中反映的明显差异)。

【讨论】:

  • 很抱歉回答我自己的问题。但我不确定我如何才能清楚且无可争议地表明我解决了自己的问题。
  • 为什么投反对票?至少有礼貌地发表评论。
  • 我发现 dialog.findViewById,如果不使用活动管理的对话框,就会引发上述异常。我在这个几乎相同的问题stackoverflow.com/questions/4826407/… 中写过它
  • 在我的情况下,我使用 setContentView(view) 和 setButton() 并且遇到了同样的问题 API17(最少 10 分钟),改用 setView(view) 解决了。
【解决方案2】:

尝试在构造函数之后立即调用.setView(view)

return new AlertDialog.Builder(context)
    .setView(view)
    .setIcon(R.drawable.myDialogIcon)
    .setTitle(R.string.myDialogTitle)
    .setPositiveButton(R.string.myDialogDone, listener)
    .create();

有帮助吗?

【讨论】:

  • 我现在也测试了你的建议。我也尝试过首先创建我的对话框并在实例化后为其分配值,但没有成功。
【解决方案3】:

这可能不是解决方案..但我对这篇文章有点惊讶:

mMyButton.setOnClickListener(new View.OnClickListener() {
    showDialog(ID_MYDIALOG);

我认为您应该在侦听器中实现 onClick 吗?我错了吗?

【讨论】:

  • 感谢您的提醒!你的评论完全正确。在我的实时代码中,它也被正确编写(实现onClick 函数)。不过,我有点急于提交我的问题(对此感到抱歉)。
  • @dbm 欢迎回答您自己的问题,尤其是在没有其他人正确回答的情况下!
猜你喜欢
  • 1970-01-01
  • 2011-05-14
  • 1970-01-01
  • 2014-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多