在.show()方法调用期间,WindowLeaked Error Android Dialog Builder

时间:2014-06-18 20:23:19

标签: builder android-dialog

这是我关于Stack Overflow的第一个问题,它与Android对话框的构建器模式有关。我最近开始阅读本书Hello Android 3rd Edition以了解如何构建基本的Android应用程序。我有基本的Java经验(两个入门编程课程和一个数据结构/算法类都使用Java作业),但我不熟悉构建器模式或Android。

我在下面显示的openNewGameDialog()方法中为警报对话框构建器执行.show()命令时收到WindowLeaked错误。我将该方法分解为构建器上的单个调用,以确定哪个是错误的来源:

// Creates a selection for game difficulty
private void openNewGameDialog() {
    AlertDialog.Builder builderDifficulty = new AlertDialog.Builder(this);
    builderDifficulty.setTitle(R.string.new_game_title);
    builderDifficulty.setItems(R.array.difficulty, 
        new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialogInterface, int i) {
                startGame(i);
            }
        });
    builderDifficulty.show(); // Throws an error
}

我研究了我在这个网站上其他地方遇到的问题,但是在大多数情况下,似乎人们在没有正确解除对话的情况下遇到了问题。我不认为同样的问题发生在我身上,但我不熟悉这样的对话框或构建器,所以我可能会弄错。代码直接来自书中的一个例子,所以我希望它能正常工作。

我正在使用Android 4.4.2模拟Nexus 5来测试该程序。以下是LogCat中的错误文本:

06-18 15:37:05.260: E/WindowManager(1089): android.view.WindowLeaked: Activity book.example.sudoku.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{b1dfa088 V.E..... R....... 0,0-1026,684} that was originally added here
06-18 15:37:05.260: E/WindowManager(1089):  at android.view.ViewRootImpl.<init>(ViewRootImpl.java:348)
06-18 15:37:05.260: E/WindowManager(1089):  at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)
06-18 15:37:05.260: E/WindowManager(1089):  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
06-18 15:37:05.260: E/WindowManager(1089):  at android.app.Dialog.show(Dialog.java:286)
06-18 15:37:05.260: E/WindowManager(1089):  at android.app.AlertDialog$Builder.show(AlertDialog.java:951)
06-18 15:37:05.260: E/WindowManager(1089):  at book.example.sudoku.MainActivity.openNewGameDialog(MainActivity.java:72)
06-18 15:37:05.260: E/WindowManager(1089):  at book.example.sudoku.MainActivity.onClick(MainActivity.java:54)
06-18 15:37:05.260: E/WindowManager(1089):  at android.view.View.performClick(View.java:4438)
06-18 15:37:05.260: E/WindowManager(1089):  at android.view.View$PerformClick.run(View.java:18422)
06-18 15:37:05.260: E/WindowManager(1089):  at android.os.Handler.handleCallback(Handler.java:733)
06-18 15:37:05.260: E/WindowManager(1089):  at android.os.Handler.dispatchMessage(Handler.java:95)
06-18 15:37:05.260: E/WindowManager(1089):  at android.os.Looper.loop(Looper.java:136)
06-18 15:37:05.260: E/WindowManager(1089):  at android.app.ActivityThread.main(ActivityThread.java:5017)
06-18 15:37:05.260: E/WindowManager(1089):  at java.lang.reflect.Method.invokeNative(Native Method)
06-18 15:37:05.260: E/WindowManager(1089):  at java.lang.reflect.Method.invoke(Method.java:515)
06-18 15:37:05.260: E/WindowManager(1089):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
06-18 15:37:05.260: E/WindowManager(1089):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
06-18 15:37:05.260: E/WindowManager(1089):  at dalvik.system.NativeStart.main(Native Method)

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

我没有在代码中的任何地方看到dialogInterface.dismiss();被调用。您可能希望在startGame(i);之上添加它。

答案 1 :(得分:0)

与你的startGame(i)方法有关。

代码运行正常没有任何问题。附上截图的完整代码

enter image description here

enter image description here

MainActivity.java

package com.example.userinput;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {

    Button send;

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

        send = (Button) findViewById(R.id.send);
        send.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                openNewGameDialog();
                Log.d("MainActivity", "Inside On Click Button");
            }
        });

    }

    // Creates a selection for game difficulty
    private void openNewGameDialog() {
        AlertDialog.Builder builderDifficulty = new AlertDialog.Builder(this);


        builderDifficulty.setTitle(R.string.new_game_title);


        builderDifficulty.setItems(R.array.difficult, 
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        //startGame(i);
                        Log.d("MainActivity", "Item on click");
                        showToast(i);
                    }
                });



        builderDifficulty.show(); // Throws an error
    }

    public void showToast(int i) {
        Log.d("MainActivity", "Inside Toast");
        Toast.makeText(getBaseContext(), "Open Dialog " + i,
                Toast.LENGTH_LONG).show();
        Log.d("MainActivity", "OpenDialog " + i);
    }

}

activity_main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${packageName}.${activityClass}" >

    <Button
        android:id="@+id/send"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_marginLeft="40dp"
        android:layout_marginTop="30dp"
        android:text="OpenNewGameDialog" />

</RelativeLayout>

difficult.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="difficult">
    <item>item1</item>
    <item>item2</item>
    <item>item3</item>    
</string-array>
</resources>

的strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">UserInput</string>
    <string name="hello_world">TextView tvTi</string>
    <string name="new_game_title">New Game Title</string>

</resources>