Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/221.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 简单的do-while循环导致崩溃_Android_While Loop - Fatal编程技术网

Android 简单的do-while循环导致崩溃

Android 简单的do-while循环导致崩溃,android,while-loop,Android,While Loop,我正在为Android开发一款智力竞赛游戏。我正在尝试生成尚未挑选的随机测验问题 (对不起,这里不合适) 您可以在public void GenerateQuiz()中找到导致崩溃的do while。 该应用程序在没有do while功能的情况下运行良好,因此一定是出了问题。 它只是不断地在6/7/8上使应用程序崩溃。随机的问题,但它至少起作用。 它所做的只是检查这个随机问题是否已经被问过了 如果是->生成一个新的随机问题,直到它成为一个新问题&以前从未被问过 如果没有->那将是下一个问题 片段

我正在为Android开发一款智力竞赛游戏。我正在尝试生成尚未挑选的随机测验问题

(对不起,这里不合适)

您可以在
public void GenerateQuiz()
中找到导致崩溃的do while。 该应用程序在没有do while功能的情况下运行良好,因此一定是出了问题。 它只是不断地在6/7/8上使应用程序崩溃。随机的问题,但它至少起作用。 它所做的只是检查这个随机问题是否已经被问过了

如果是->生成一个新的随机问题,直到它成为一个新问题&以前从未被问过

如果没有->那将是下一个问题

片段:

public void GenerateQuiz() {
    do{
        QuizID = ShuffleQuiz();
    }while(CheckIfQuestionIsNew(QuizID)==false);
有三个困难:简单、中等和困难。他们每个人只有10个问题=总共30个问题。问题由随机生成的1-10个整数生成。 一旦用户完成10个问题,应用程序将把难度调到下一个最高点。示例:如果第10题(简单)回答正确,则难度将变为中等。一旦你完成第十道中等题,它将变为硬题

已更新 LogCat崩溃后的错误消息:

05-12 16:45:00.232 14067-14067/?E/ClockAlarmWidget﹕ [AlarmWidgetIdManager]getListItem():itemIndex=0,widgetID:1 05-12 16:45:00.232 14067-14067/? E/ClockAlarmWidget﹕ [AlarmWidgetIdManager] getListItem():ItemIndex超过ListItemCount。itemIndex=1 05-12 16:45:00.232 14067-14067/? E/ClockAlarmWidget﹕ [AlarmWidgetIdManager] getListItem():itemIndex=1,widgetID:1

资料来源:

 boolean CheckIfQuestionIsNew(int element) {
        List<Integer> ListDifficulty = new ArrayList<Integer>();

        //#########GET ARRAYLIST#########
        //Determine the Difficulty since each Difficulty got it's own arraylist.
        if (QuizDifficulty==1){//Example: If Difficulty==1, copy it's arrays to the new list of array.
            ListDifficulty.addAll(QuizIDsPassedD1);
        }else if (QuizDifficulty==2){
            ListDifficulty.addAll(QuizIDsPassedD2);
        }else if (QuizDifficulty==3){
            ListDifficulty.addAll(QuizIDsPassedD3);
        }

        if (ListDifficulty.contains(element))
            return false;

        //#########UPDATE ARRAYLIST#########
        // If Question was not asked before then --> Add the new question ID to the arraylist
        ListDifficulty.add(element);


        //#########SAVE NEW ARRAYLIST#########
        //Now it needs to determine the difficulty aggain to update its arraylist with the new items.
        if (QuizDifficulty==1){
            QuizIDsPassedD1.removeAll((QuizIDsPassedD1));//Remove All (Double Make Sure)
            QuizIDsPassedD1.addAll(ListDifficulty);//Transfer new Arraylist to the difficultyies array list
        }else if (QuizDifficulty==2){
            QuizIDsPassedD2.removeAll((QuizIDsPassedD2));
            QuizIDsPassedD2.addAll(ListDifficulty);
        }else if (QuizDifficulty==3){
            QuizIDsPassedD3.removeAll((QuizIDsPassedD3));
            QuizIDsPassedD3.addAll(ListDifficulty);
        }
        return true;
    }
布尔CheckIfQuestionIsNew(int元素){
List ListDemobility=新建ArrayList();
//#########获取阵列列表#########
//确定难度,因为每个难度都有自己的arraylist。
如果(QuizDifficulty==1){//示例:如果难度==1,则将其数组复制到新的数组列表中。
列表难度.addAll(QuizIDsPassedD1);
}else if(QuizDifficity==2){
列表难度.addAll(QuizIDsPassedD2);
}else if(QuizDifficity==3){
列表难度.addAll(QuizIDsPassedD3);
}
if(listDemobility.contains(元素))
返回false;
//#########更新ARRAYLIST#########
//如果之前未询问问题,则-->将新问题ID添加到arraylist
添加(元素);
//#########保存新ARRAYLIST#########
//现在,它需要确定使用新项更新其arraylist的难度。
如果(QuizDifficity==1){
QuizIDsPassedD1.removeAll((QuizIDsPassedD1));//全部删除(双重确认)
QuizIDsPassedD1.addAll(ListOfficity);//将新的Arraylist传输到困难数组列表
}else if(QuizDifficity==2){
QuizIDsPassedD2.移除所有((QuizIDsPassedD2));
QuizIDsPassedD2.addAll(列表难度);
}else if(QuizDifficity==3){
移除所有((QuizIDsPassedD3));
QuizIDsPassedD3.addAll(列表难度);
}
返回true;
}

改为使用下面的代码,然后检查CheckIfQuestionIsNew(QuizID)是否返回布尔值

 do{
        QuizID = ShuffleQuiz();
    }while(CheckIfQuestionIsNew(QuizID));
在“DO/WHILE”循环中,大括号之间的代码至少执行一次。因此,如果您在其中遇到异常,这应该是因为您正在以不应该的方式进入循环。考虑使用AWS子句代替?< /P> 如果这是导致崩溃的大括号之间的一行,请添加该方法的代码


另外,请添加日志猫。

问题在于
OutOfMemoryException

java.lang.OutOfMemoryError at java.util.ArrayList.addAll(ArrayList.java:194) at 
de.hackert.wwequiz2014.QuizScreen.CheckIfQuestionIsNew(QuizScreen.java:49) at 
private void bindAnswerToButton(Button button, Answer answer) {
    int answerTextResId = answer.getAnswerTextResId();
    button.setText(answerTextResId);

    button.setOnClickListener(new AnswerClickListener(answer));
}
private void gotoNextQuestion() {
    this.questionIndex++;
    moveToQuestion(this.questionIndex);
}
这是由于在
CheckIfQuestionIsNew()
方法中向
ArrayList
中添加项造成的。很可能在那里的某个地方有一个无限循环,因为您必须向
列表视图添加大量项(我说的是数千到数百万项),以获得
OutOfMemoryException
。我会检查你的代码,但我认为你可能会更快地识别出确切的错误,因为你熟悉代码

编辑: 我想我发现了错误

你到底想在这里做什么:

ListDifficulty = QuizIDsPassedD1;
ListDifficulty.addAll(QuizIDsPassedD1);
对我来说没什么意义。这将与do/while循环一次又一次地重复列表中的所有项目,这很可能是罪魁祸首

编辑: 我在
CheckIfQuestionIsNew()
中注释了您的代码:

因为你看不到什么特别的东西。它的成员变量包括问题文本的资源id、图像的资源id和答案的
列表
。此外,我还添加了一个
addAnswer()
方法,方便地为问题添加答案

答案
类如下所示:

public class Question {

    private final int imageResId;
    private final int questionTextResId;
    private final List<Answer> answers = new ArrayList<Answer>();

    public Question(int questionTextResId, int imageResId) {
        this.imageResId = imageResId;
        this.questionTextResId = questionTextResId;
    }

    public Question addAnswer(int answerTextResId, boolean correct) {
        Answer answer = new Answer(answerTextResId, correct);
        this.answers.add(answer);
        return this;
    }

    public int getQuestionTextResId() {
        return questionTextResId;
    }

    public int getImageResId() {
        return imageResId;
    }

    public List<Answer> getAnswers() {
        return answers;
    }
}
public class Answer {

    private final int answerTextResId;
    private final boolean correct;

    public Answer(int answerTextResId, boolean correct) {
        this.answerTextResId = answerTextResId;
        this.correct = correct;
    }

    public int getAnswerTextResId() {
        return answerTextResId;
    }

    public boolean isCorrect() {
        return correct;
    }
}
private void startGame() {
    Collections.shuffle(this.easyQuestions);
    Collections.shuffle(this.mediumQuesitons);
    Collections.shuffle(this.hardQuestions);

    this.questionQueue.clear();
    this.questionQueue.addAll(this.easyQuestions);
    this.questionQueue.addAll(this.mediumQuesitons);
    this.questionQueue.addAll(this.hardQuestions);
    this.questionIndex = 0;

    moveToQuestion(0);
}
private void moveToQuestion(int index) {
    // First we check if we have reached the end of the queue
    if(index < this.questionQueue.size()) {

        // If not we get the current question
        Question question = this.questionQueue.get(index);

        // Here we set the question text to the TextView
        int questionTextResId = question.getQuestionTextResId();
        this.textViewFrage.setText(questionTextResId);

        // And here the question image to the ImageView.
        int imageResId = question.getImageResId();
        this.imageViewBild.setImageResource(imageResId);

        // We get the answers from the question and create two count variables for convenience
        List<Answer> answers = question.getAnswers();
        int answerCount = answers.size();
        int buttonCount = this.answerButtons.length;

        // We start a loop through all the answer buttons
        for(int i = 0; i < buttonCount; i++) {
            // We get the current button from the Button[] which contains all the answer buttons
            Button button = this.answerButtons[i];

            // There might not be as many answers as there are buttons, that's what we check here
            if(i < answerCount) {
                // If there is an answer for this button make it visible
                button.setVisibility(View.VISIBLE);

                // We get the answer and bind to the button by calling bindAnswerToButton()
                Answer answer = answers.get(i);
                bindAnswerToButton(button, answer);
            } else {
               // If no answer exists for the Button we make it invisible.
               button.setVisibility(View.GONE);
            }
        }
    } else {
        // We have reached the end of the queue
        // You have to decide what happens when the game is won
        Toast toast = Toast.makeText(this, R.string.game_won, Toast.LENGTH_SHORT);
        toast.show();
    }
}
private class AnswerClickListener implements View.OnClickListener {

    private final Answer answer;

    private AnswerClickListener(Answer answer) {
        this.answer = answer;
    }

    @Override
    public void onClick(View v) {
        if(this.answer.isCorrect()) {
            gotoNextQuestion();
        } else {
            // You have to decide what happens when someone picks the wrong answer
            Toast toast = Toast.makeText(QuizScreen.this, R.string.toast_wrong_answer, Toast.LENGTH_SHORT);
            toast.show();
        }
    }
}
正如您再次看到的,没有什么特别的,但是这里只有两个成员变量,一个是答案文本的资源id,另一个是布尔值,如果这个答案正确与否

在向您展示我改进的
QuizScreen
活动的完整代码之前,我将向您解释我所做的所有更改及其工作原理。首先,我为您使用的所有
视图创建了成员变量。您不应该经常调用
findViewById()
。将引用保存在成员变量中时,不必再次调用
findViewById()

private Button buttonAntwort1;
private Button buttonAntwort2;
private Button buttonAntwort3;
private Button buttonAntwort4;
private TextView textViewFrage;
private ImageView imageViewBild;

private Button[] answerButtons;

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

    this.imageViewBild = (ImageView) findViewById(R.id.imageViewBild);
    this.textViewFrage = (TextView) findViewById(R.id.textViewFrage);
    this.buttonAntwort1 = (Button) findViewById(R.id.buttonAntwort1);
    this.buttonAntwort2 = (Button) findViewById(R.id.buttonAntwort2);
    this.buttonAntwort3 = (Button) findViewById(R.id.buttonAntwort3);
    this.buttonAntwort4 = (Button) findViewById(R.id.buttonAntwort4);

    this.answerButtons = new Button[] { this.buttonAntwort1, this.buttonAntwort2, this.buttonAntwort3, this.buttonAntwort4 };

    createQuestions();
    startGame();
}
如您所见,我还创建了一个
按钮[]
,其中包含所有可用于回答问题的
按钮。我的解决方案在这方面是完全灵活的。您可以有
问题
和任意数量的
答案
,每个
问题
都可以有不同数量的
答案
。您只需确保
按钮[]
中有足够的
按钮。如果您想让
问题
有4个以上的答案,只需添加为
private void moveToQuestion(int index) {
    // First we check if we have reached the end of the queue
    if(index < this.questionQueue.size()) {

        // If not we get the current question
        Question question = this.questionQueue.get(index);

        // Here we set the question text to the TextView
        int questionTextResId = question.getQuestionTextResId();
        this.textViewFrage.setText(questionTextResId);

        // And here the question image to the ImageView.
        int imageResId = question.getImageResId();
        this.imageViewBild.setImageResource(imageResId);

        // We get the answers from the question and create two count variables for convenience
        List<Answer> answers = question.getAnswers();
        int answerCount = answers.size();
        int buttonCount = this.answerButtons.length;

        // We start a loop through all the answer buttons
        for(int i = 0; i < buttonCount; i++) {
            // We get the current button from the Button[] which contains all the answer buttons
            Button button = this.answerButtons[i];

            // There might not be as many answers as there are buttons, that's what we check here
            if(i < answerCount) {
                // If there is an answer for this button make it visible
                button.setVisibility(View.VISIBLE);

                // We get the answer and bind to the button by calling bindAnswerToButton()
                Answer answer = answers.get(i);
                bindAnswerToButton(button, answer);
            } else {
               // If no answer exists for the Button we make it invisible.
               button.setVisibility(View.GONE);
            }
        }
    } else {
        // We have reached the end of the queue
        // You have to decide what happens when the game is won
        Toast toast = Toast.makeText(this, R.string.game_won, Toast.LENGTH_SHORT);
        toast.show();
    }
}
private void bindAnswerToButton(Button button, Answer answer) {
    int answerTextResId = answer.getAnswerTextResId();
    button.setText(answerTextResId);

    button.setOnClickListener(new AnswerClickListener(answer));
}
private class AnswerClickListener implements View.OnClickListener {

    private final Answer answer;

    private AnswerClickListener(Answer answer) {
        this.answer = answer;
    }

    @Override
    public void onClick(View v) {
        if(this.answer.isCorrect()) {
            gotoNextQuestion();
        } else {
            // You have to decide what happens when someone picks the wrong answer
            Toast toast = Toast.makeText(QuizScreen.this, R.string.toast_wrong_answer, Toast.LENGTH_SHORT);
            toast.show();
        }
    }
}
private void gotoNextQuestion() {
    this.questionIndex++;
    moveToQuestion(this.questionIndex);
}
public static class QuizScreen extends ActionBarActivity  {

    private final List<Question> easyQuestions = new ArrayList<Question>();
    private final List<Question> mediumQuesitons = new ArrayList<Question>();
    private final List<Question> hardQuestions = new ArrayList<Question>();

    private final List<Question> questionQueue = new ArrayList<Question>();
    private int questionIndex = 0;

    private Button buttonAntwort1;
    private Button buttonAntwort2;
    private Button buttonAntwort3;
    private Button buttonAntwort4;
    private TextView textViewFrage;
    private ImageView imageViewBild;

    private Button[] answerButtons;

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

        this.imageViewBild = (ImageView) findViewById(R.id.imageViewBild);
        this.textViewFrage = (TextView) findViewById(R.id.textViewFrage);
        this.buttonAntwort1 = (Button) findViewById(R.id.buttonAntwort1);
        this.buttonAntwort2 = (Button) findViewById(R.id.buttonAntwort2);
        this.buttonAntwort3 = (Button) findViewById(R.id.buttonAntwort3);
        this.buttonAntwort4 = (Button) findViewById(R.id.buttonAntwort4);

        this.answerButtons = new Button[] { this.buttonAntwort1, this.buttonAntwort2, this.buttonAntwort3, this.buttonAntwort4 };

        createQuestions();
        startGame();
    }

    private void createQuestions() {
        newEasy(R.string.question1_text, R.drawable.question1_picture1)
                .addAnswer(R.string.question1_answer1, false).addAnswer(R.string.question1_answer2, true)
                .addAnswer(R.string.question1_answer3, false).addAnswer(R.string.question1_answer4, false);


        newMedium(R.string.question2_text, R.drawable.question2_picture1)
                .addAnswer(R.string.question2_answer1, false).addAnswer(R.string.question2_answer2, true)
                .addAnswer(R.string.question2_answer3, false).addAnswer(R.string.question2_answer4, false);


        newHard(R.string.question3_text, R.drawable.question3_picture1)
                .addAnswer(R.string.question3_answer1, false).addAnswer(R.string.question3_answer2, true)
                .addAnswer(R.string.question3_answer3, false).addAnswer(R.string.question3_answer4, false);

    }

    private Question newEasy(int questionTextResId, int imageResId) {
        Question question = new Question(questionTextResId, imageResId);
        this.easyQuestions.add(question);
        return question;
    }

    private Question newMedium(int questionTextResId, int imageResId) {
        Question question = new Question(questionTextResId, imageResId);
        this.mediumQuesitons.add(question);
        return question;
    }

    private Question newHard(int questionTextResId, int imageResId) {
        Question question = new Question(questionTextResId, imageResId);
        this.hardQuestions.add(question);
        return question;
    }

    private void startGame() {
        Collections.shuffle(this.easyQuestions);
        Collections.shuffle(this.mediumQuesitons);
        Collections.shuffle(this.hardQuestions);

        this.questionQueue.clear();
        this.questionQueue.addAll(this.easyQuestions);
        this.questionQueue.addAll(this.mediumQuesitons);
        this.questionQueue.addAll(this.hardQuestions);
        this.questionIndex = 0;

        moveToQuestion(0);
    }

    private void moveToQuestion(int index) {
        if(index < this.questionQueue.size()) {
            Question question = this.questionQueue.get(index);

            int questionTextResId = question.getQuestionTextResId();
            this.textViewFrage.setText(questionTextResId);

            int imageResId = question.getImageResId();
            this.imageViewBild.setImageResource(imageResId);

            List<Answer> answers = question.getAnswers();
            int answerCount = answers.size();
            int buttonCount = this.answerButtons.length;

            for(int i = 0; i < buttonCount; i++) {
                Button button = this.answerButtons[i];

                if(i < answerCount) {
                    button.setVisibility(View.VISIBLE);

                    Answer answer = answers.get(i);
                    bindAnswerToButton(button, answer);
                } else {
                   button.setVisibility(View.GONE);
                }
            }
        }
    }

    private void gotoNextQuestion() {
        this.questionIndex++;
        moveToQuestion(this.questionIndex);
    }

    private void bindAnswerToButton(Button button, Answer answer) {
        int answerTextResId = answer.getAnswerTextResId();
        button.setText(answerTextResId);
        button.setOnClickListener(new AnswerClickListener(answer));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.quiz_screen, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private class AnswerClickListener implements View.OnClickListener {

        private final Answer answer;

        private AnswerClickListener(Answer answer) {
            this.answer = answer;
        }

        @Override
        public void onClick(View v) {
            if(this.answer.isCorrect()) {
                gotoNextQuestion();
            } else {
                Toast toast = Toast.makeText(QuizScreen.this, R.string.toast_wrong_answer, Toast.LENGTH_SHORT); 
                toast.show();
            }
        }
    }
}