当应答2:nd对话窗口时,我的应用程序崩溃

时间:2014-04-26 12:26:48

标签: java android nullpointerexception

我的方法有一个奇怪的问题就是创建有问题的拨号。基本上我所做的就是创建一个带有问题和标识符的hashmap表,我在对话框窗口的正负按钮上使用if语句。

这是程序代码:

public class QuestionsActivity extends Activity {
String question = null;
String identifier = null;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.test_layout);


    // 0 = call showRiskEvaluationDialog() on button NO.  1 = call showRiskEvaluationDialog(); on button YES
    Map<String, String> question_map = new HashMap<String, String>();
    question_map.put("Have you cut the power?", "0");
    question_map.put("Have you not cut the power?", "1");
    question_map.put("Do you know your work assignment?", "0");
    question_map.put("Don't you know your work assignment?", "1");

    //For loop to extract a question and identifier from the hashmap
    for(Entry<String, String> entry : question_map.entrySet()) 
    {
        question = entry.getKey();
        identifier = entry.getValue();

        create_dialog_method(question);
    }

}

/**
 * Method to create a dialogbox with a question and YES, NO buttons
 * @param question_param
 */
public void create_dialog_method(String question_param) {
    AlertDialog.Builder alert = new AlertDialog.Builder(this);

    alert.setTitle("Titel");
    alert.setMessage(question_param);

    alert.setPositiveButton("YES", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {

            if (identifier.equalsIgnoreCase("1")) {

                showRiskEvaluationDialog();

                identifier = null;
            } else if (identifier.equalsIgnoreCase("0")) {

                Toast.makeText(getApplicationContext(), "Saved",
                       Toast.LENGTH_SHORT).show();

                identifier = null;

            }

        }
    });

    alert.setNegativeButton("NO", new DialogInterface.OnClickListener(){
        public void onClick(DialogInterface dialog, int whichButton) {

            if (identifier.equalsIgnoreCase("0")) {

                showRiskEvaluationDialog();

                identifier = null;

            } else if (identifier.equalsIgnoreCase("1")) {

                Toast.makeText(getApplicationContext(), "Saved",
                           Toast.LENGTH_SHORT).show();

                identifier = null;
            }

        }
    });

    alert.show();
}

问题:首先,它似乎以奇怪的顺序循环遍历hashmap。它首先是“你有没有削减力量?”,因此跳过第一个问题。 运行程序时的主要问题是在我回答了2:nd对话框弹出窗口后应用程序崩溃。基本上它完美地完成了1个问题,但是当我回答2:nd问题时,无论我回答什么按钮,它都会发生冲突。

这是错误:

04-26 14:13:35.163: E/AndroidRuntime(7953): FATAL EXCEPTION: main
04-26 14:13:35.163: E/AndroidRuntime(7953): java.lang.NullPointerException
04-26 14:13:35.163: E/AndroidRuntime(7953):     at   com.example.ovakoappen.QuestionsActivity$2.onClick(QuestionsActivity.java:85)
04-26 14:13:35.163: E/AndroidRuntime(7953):     at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:185)
04-26 14:13:35.163: E/AndroidRuntime(7953):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-26 14:13:35.163: E/AndroidRuntime(7953):     at android.os.Looper.loop(Looper.java:137)
04-26 14:13:35.163: E/AndroidRuntime(7953):     at android.app.ActivityThread.main(ActivityThread.java:5279)
04-26 14:13:35.163: E/AndroidRuntime(7953):     at java.lang.reflect.Method.invokeNative(Native Method)
04-26 14:13:35.163: E/AndroidRuntime(7953):     at java.lang.reflect.Method.invoke(Method.java:511)
04-26 14:13:35.163: E/AndroidRuntime(7953):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
04-26 14:13:35.163: E/AndroidRuntime(7953):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
04-26 14:13:35.163: E/AndroidRuntime(7953):     at dalvik.system.NativeStart.main(Native Method)

4 个答案:

答案 0 :(得分:0)

关于第一个&#34;问题&#34;与顺序:哈希映射不保证特定的顺序。更为明确的是,订单甚至不必随时间保持不变。你将不得不使用别的东西。

答案 1 :(得分:0)

对于您的订单问题,您可以看到使用LinkedHashMap来获取订单中的商品(source

对于您遇到的崩溃,这是因为所有对话框都是在您的活动的onCreate方法中一次创建的,一旦您验证了对话框,您的变量identifier就会变为空。您应该一次只创建一个对话框,并在对话框的dismissListener中创建以下内容。有关解雇听众的详细信息here

答案 2 :(得分:0)

代码中存在逻辑错误:

在循环中创建N个对话框(此处为至少4个)。然而,每个对话框都使用相同的question / identifier个变量。

含义:第一个将在退出后更改identifier值,此值将使用第二个对话框。 Android中的对话是非阻塞的。当您显示一个对话框时,create_dialog_method()的执行结束并且for循环正在运行!即使您仍然可以看到对话框,也会在其上创建另一个对话框。

实际上,你有4个逐个创建的对话框,但都显示了一个,但是一个可见。

然后在onClick()方法中将identifier设置为null。这是第二个对话框将看到的值,这就是它崩溃的原因。

至少有两种解决方案:

  1. 一次只创建一个对话框,在使用是/否按钮或关闭侦听器关闭它后创建一个新对话框。
  2. 创建您自己的对话框类并在那里传递问题/标识符 - 因此它们独立于您的主要问题图。

答案 3 :(得分:0)

  1. 对于订购问题:您可以使用LinkedHashMap来确保订购。

  2. NullPointerException是在null对象上调用方法equalsIgnoreCase的结果,在第一次迭代中将identifier设置为null:您应该question 1}}和identifier方法参数而不是字段。

  3. 这是更改后的代码:

        public class QuestionsActivity extends Activity {
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.test_layout);
    
           // false = call showRiskEvaluationDialog() on button NO
           // true  = call showRiskEvaluationDialog() on button YES
           Map<String, Boolean> question_map = new LinkedHashMap<String, Boolean>();
           question_map.put("Have you cut the power?", false);
           question_map.put("Have you not cut the power?", true);
           question_map.put("Do you know your work assignment?", false);
           question_map.put("Don't you know your work assignment?", true);
    
           // For loop to extract a question and identifier from the Map
           for (Entry<String, Boolean> entry : question_map.entrySet()){
              create_dialog_method(entry.getKey(), entry.getValue());
           }
        }
    
        /**
         * Method to create a dialogbox with a question and YES, NO buttons
         *
         * @param question_param
         * @param identifier
         */
        public void create_dialog_method(String question_param, final boolean identifier) {
           AlertDialog.Builder alert = new AlertDialog.Builder(this);
    
           alert.setTitle("Title");
           alert.setMessage(question_param);
    
           alert.setPositiveButton("YES", new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int whichButton) {
    
                 if (identifier)
                    showRiskEvaluationDialog();
                 else
                    Toast.makeText(getApplicationContext(), "Saved",
                          Toast.LENGTH_SHORT).show();
              }
           });
    
           alert.setNegativeButton("NO", new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int whichButton) {
    
                 if (identifier)
                    Toast.makeText(getApplicationContext(), "Saved",
                          Toast.LENGTH_SHORT).show();
                 else
                    showRiskEvaluationDialog();
              }
           });
           alert.show();
        }
    
        private void showRiskEvaluationDialog() {}
        }