Android程序在点击后挂起

时间:2017-03-28 17:10:46

标签: android hang

我正在写一个Android应用程序,通过多种选择来询问我的饮料配方。按下选项后,应用程序会为正确答案着色并生成新问题。然而,经过一些轮次,它挂起,我找不到原因。我在下面发布了代码和布局。

package com.example.frances.rocksdrinks;

import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;


public class Menu extends AppCompatActivity {
String[] allDrinks = {"BOURBON ON THE ROCKS", "SCOTCH ON THE ROCKS", "TOP SHELF SCOTCH ON THE ROCKS", "BLACK RUSSIAN", "SICILIAN KISS",
        "GOD MOTHER", "GOD FATHER", "RUSTY NAIL", "NUTTY IRISHMAN", "STINGER", "KAMIKAZE", "PURPLE HOOTER", "WINDEX",
        "RASPBERRY KAMIKAZE", "MUDSLIDE", "AFTER FIVE", "B~51", "B~52", "B~53", "OATMEAL COOKIE"};

Map<String, String> liquor = new HashMap<String, String>()
{{
    put("bourbon on the rocks", "1 1/2 oz Bourbon Whiskey");
    put("scotch on the rocks", "1 1/2 oz Scotch Whiskey");
    put("top shelf scotch on the rocks", "1 1/2 oz Scotch Whiskey");
    put("black russian", "1 1/4 oz Vodka & 3/4 oz Kahlua");
    put("sicilian kiss", "1 1/4 oz Southern Comfort & 3/4 oz Amaretto");
    put("god mother", "1 1/4 oz Vodka & 3/4 oz Amaretto");
    put("god father", "1 1/4 oz Scotch & 3/4 oz Amaretto");
    put("rusty nail", "1 1/4 oz Scotch & 3/4 oz Drambuie");
    put("Nutty Irishman", "1 1/4 oz Baileys & 3/4 oz Frangelico");
    put("stinger", "1 1/4 oz Brandy & 3/4 oz White Creme De Menthe");
    put("kamikaze", "1 1/4 oz Vodka & 3/4 oz Triple Sec");
    put("purple hooter", "1 1/4 oz Vodka & 3/4 oz Chambord");
    put("windex", "1 1/4 oz Vodka & 3/4 oz Blue Curacao");
    put("raspberry kamikaze", "1 1/4 oz Raspberry Vodka & 3/4 oz Triple Sec");
    put("mudslide", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Vodka");
    put("after five", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Peppermint Schnapps");
    put("b~51", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Frangelico");
    put("b~52", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Grand Marnier");
    put("b~53", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Amaretto");
    put("oatmeal cookie", "1/2 oz Kahlua & 1/2 oz Baileys & 1/2 oz Goldschlager");
}};

Map<String, String> mixer = new HashMap<String, String>()
{{
    put("bourbon on the rocks", "");
    put("scotch on the rocks", "");
    put("top shelf scotch on the rocks", "");
    put("black russian", "");
    put("sicilian kiss", "");
    put("god mother", "");
    put("god father", "");
    put("rusty nail", "");
    put("Nutty Irishman", "");
    put("stinger", "");
    put("kamikaze", "");
    put("purple hooter", "");
    put("windex", "");
    put("raspberry kamikaze", "");
    put("mudslide", "");
    put("after five", "");
    put("b~51", "");
    put("b~52", "");
    put("b~53", "");
    put("oatmeal cookie", "");
}};

Map<String, String> garnish = new HashMap<String, String>()
{{
    put("bourbon on the rocks", "None");
    put("scotch on the rocks", "None");
    put("top shelf scotch on the rocks", "None");
    put("black russian", "None");
    put("sicilian kiss", "None");
    put("god mother", "None");
    put("god father", "None");
    put("rusty nail", "Lemon Twist");
    put("Nutty Irishman", "None");
    put("stinger", "Mint Leaf");
    put("kamikaze", "Splash Lime Juice");
    put("purple hooter", "Splash Lime Juice");
    put("windex", "Splash Lime Juice");
    put("raspberry kamikaze", "Splash Lime Juice");
    put("mudslide", "None");
    put("after five", "None");
    put("b~51", "None");
    put("b~52", "None");
    put("b~53", "None");
    put("oatmeal cookie", "None");
}};

Random r = new Random();

TextView choice1, choice2, choice3, choice4, answer, question;
String ans;
int qIndex;
String[] choices;
TextView correct;
Handler handler;

TextView pressed;

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

    choice1 = (TextView) findViewById(R.id.choice1);
    choice2 = (TextView) findViewById(R.id.choice2);
    choice3 = (TextView) findViewById(R.id.choice3);
    choice4 = (TextView) findViewById(R.id.choice4);

    answer = (TextView) findViewById(R.id.answer);
    question = (TextView) findViewById(R.id.question);

    handler = new Handler();

    createQuestion();
    createAnswers();

    question.setTextSize(21);
}

public void choice(View v)
{
    pressed = (TextView) findViewById(v.getId());
    answer.setVisibility(View.VISIBLE);

    if (pressed.getText().toString() == choices[0])
    {
        pressed.setTextColor(Color.parseColor("#00BF00"));
        answer.setText("CORRECT!");
        answer.setTextColor(Color.parseColor("#00BF00"));
    }
    else
    {
        pressed.setTextColor(Color.parseColor("#F60000"));
        answer.setText("WRONG!");
        answer.setTextColor(Color.parseColor("#F60000"));
        correct.setTextColor(Color.parseColor("#00BF00"));
    }

    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            pressed.setTextColor(Color.parseColor("#777777"));
            correct.setTextColor(Color.parseColor("#777777"));
            answer.setVisibility(View.GONE);

            createQuestion();
            createAnswers();
        }
    }, 3000);

}

//if answer is a recipe, use 20sp as font size
private void createQuestion()
{
    String[] qs = {"Which drink contains ", "What garnish does drink contain", "What mixer does drink use",
            "Which of the following describes a drink"};


    int i = r.nextInt(allDrinks.length);
    ans = allDrinks[i];

    qIndex = r.nextInt(qs.length);
    String q = "";

    if (qIndex != 0)
    {
        q = qs[qIndex].replace("drink", ans);
    }
    else
    {
        q = qs[qIndex] + liquor.get(ans.toLowerCase());

        if (!mixer.get(ans.toLowerCase()).isEmpty())
        {
            q += " + " + mixer.get(ans.toLowerCase());;
        }

        if (!garnish.get(ans.toLowerCase()).equals("None"))
        {
            q += " + " + garnish.get(ans.toLowerCase());
        }
    }

    question.setText(q + "?");
}

private void createAnswers()
{
    choices = new String[4];
    int count = 1;
    String a = "";

    if (qIndex == 3)
    {
        choices[0] = liquor.get(ans.toLowerCase());
        if (!mixer.get(ans.toLowerCase()).isEmpty())
        {
            choices[0] += ", " + mixer.get(ans.toLowerCase());
        }

        if (!garnish.get(ans.toLowerCase()).equals("None"))
        {
            choices[0] += ", " + garnish.get(ans.toLowerCase());
        }

        while (count != 4)
        {
            int i = r.nextInt(allDrinks.length);
            if (allDrinks[i] != ans)
            {
                a = liquor.get(allDrinks[i].toLowerCase());

                if (!mixer.get(ans.toLowerCase()).isEmpty())
                {
                    a += ", " + mixer.get(allDrinks[i].toLowerCase());
                }

                if (!garnish.get(allDrinks[i].toLowerCase()).equals("None"))
                {
                    a += ", " + garnish.get(allDrinks[i].toLowerCase());
                }

                if (!Arrays.asList(choices).contains(a))
                {
                    choices[count] = a;
                    count++;
                }

            }
        }
    }
    else if (qIndex == 0)
    {
        choices[0] = ans;

        while (count != 4)
        {
            int i = r.nextInt(allDrinks.length);
            if (allDrinks[i] != ans)
            {
                a = allDrinks[i];

                if (!Arrays.asList(choices).contains(a))
                {
                    choices[count] = a;
                    count++;
                }
            }

        }
    }
    else if (qIndex == 1)
    {
        String[] g = {"Splash Coke", "Splash Grenadine", "Splash Sprite", "None"};
        choices[0] = garnish.get(ans.toLowerCase());

        while (count != 4)
        {
            int i = r.nextInt(g.length);
            if (g[i] != choices[0])
            {
                a = g[i];

                if (!Arrays.asList(choices).contains(a))
                {
                    choices[count] = a;
                    count++;
                }
            }
        }
    }
    else
    {
        choices[0] = mixer.get(ans.toLowerCase());

        while (count != 4)
        {
            int i = r.nextInt(allDrinks.length);
            if (mixer.get(allDrinks[i].toLowerCase()) != choices[0])
            {
                a = mixer.get(allDrinks[i].toLowerCase());
                if (!Arrays.asList(choices).contains(a))
                {
                    choices[count] = a;
                    count++;
                }
            }
        }
    }

    TextView[] cs = {choice1, choice2, choice3, choice4};
    cs = shuffle(cs);
    correct = cs[0];

    for (int i = 0; i<4; i++)
    {
        if (qIndex == 3)
        {
            cs[i].setTextSize(12);
        }
        else
        {
            cs[i].setTextSize(18);
        }
        cs[i].setText(choices[i]);
    }
}

private TextView[] shuffle(TextView[] arr)
{
    int index;
    TextView temp;
    for (int i = arr.length - 1; i > 0; i--)
    {
        index = r.nextInt(i + 1);
        temp = arr[index];
        arr[index] = arr[i];
        arr[i] = temp;
    }
    return arr;
}

}

这是布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:id="@+id/question"
    android:layout_width="wrap_content"
    android:layout_height="140sp"
    android:layout_gravity="center_horizontal"
    android:layout_marginTop="20sp"
    android:textSize="25sp"
    android:layout_marginLeft="20sp"
    android:layout_marginRight="20sp"
    android:gravity="center"
    android:textColor="@color/black"
    android:text="Which drink contains 1/2 oz Jagermeister1/2 oz Peach Schnapps + Cranberry Juice"/>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="300sp"
    android:layout_marginTop="30sp">

    <TextView
        android:id="@+id/choice1"
        android:layout_marginLeft="0sp"
        android:background="@drawable/shadowsmall"
        android:layout_width="180sp"
        android:layout_height="130sp"
        android:text="Screwdriver"
        android:textSize="23sp"
        android:textColor="#777777"
        android:clickable="true"
        android:onClick="choice"
        android:gravity="center"/>

    <TextView
        android:id="@+id/choice2"
        android:layout_marginLeft="180sp"
        android:background="@drawable/shadowsmall"
        android:layout_width="180sp"
        android:layout_height="130sp"
        android:text="Screwdriver"
        android:textSize="23sp"
        android:textColor="#777777"
        android:clickable="true"
        android:onClick="choice"
        android:gravity="center"/>

    <TextView
        android:id="@+id/choice3"
        android:layout_marginTop="130sp"
        android:layout_marginLeft="0sp"
        android:background="@drawable/shadowsmall"
        android:layout_width="180sp"
        android:layout_height="130sp"
        android:text="Screwdriver"
        android:textSize="23sp"
        android:textColor="#777777"
        android:clickable="true"
        android:onClick="choice"
        android:gravity="center"/>

    <TextView
        android:id="@+id/choice4"
        android:layout_marginTop="130sp"
        android:layout_marginLeft="180sp"
        android:background="@drawable/shadowsmall"
        android:layout_width="180sp"
        android:layout_height="130sp"
        android:text="1 oz vodka, 50/50 orange and cranberry, lime"
        android:textSize="23sp"
        android:onClick="choice"
        android:textColor="#777777"
        android:clickable="true"
        android:gravity="center"/>

</RelativeLayout>

<TextView
    android:layout_marginTop="-40sp"
    android:id="@+id/answer"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:textSize="30sp"
    android:textColor="@color/green"
    android:textStyle="bold"/>

</LinearLayout>

logcat在开始挂起时提供此输出

03-28 12:51:05.460 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 9.490ms
03-28 12:51:15.605 29897-29913/com.example.frances.rocksdrinks I/art: Background sticky concurrent mark sweep GC freed 14222(509KB) AllocSpace objects, 0(0B) LOS objects, 24% free, 1825KB/2MB, paused 5.062ms total 11.585ms
03-28 12:51:23.159 29897-29913/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 10.660ms for cause Background
03-28 12:52:48.768 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 6.314ms
03-28 12:52:58.857 29897-29913/com.example.frances.rocksdrinks I/art: Background sticky concurrent mark sweep GC freed 30454(1094KB) AllocSpace objects, 0(0B) LOS objects, 38% free, 1708KB/2MB, paused 5.259ms total 13.447ms
03-28 12:54:07.970 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.891ms
03-28 12:54:24.523 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.254ms
03-28 12:54:45.569 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.900ms
03-28 12:54:49.078 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 8.536ms
03-28 12:54:57.595 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.742ms
03-28 12:55:30.525 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 7.450ms for cause HeapTrim
03-28 12:55:34.194 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.670ms
03-28 12:55:56.904 29897-29913/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.412ms
03-28 12:56:09.293 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 6.397ms
03-28 12:56:37.481 29897-29913/com.example.frances.rocksdrinks I/art: Background sticky concurrent mark sweep GC freed 29570(1064KB) AllocSpace objects, 0(0B) LOS objects, 38% free, 1688KB/2MB, paused 10.745ms total 18.296ms
03-28 12:56:42.810 29897-29913/com.example.frances.rocksdrinks W/art: Suspending all threads took: 6.896ms
03-28 12:57:03.446 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 8.611ms
03-28 12:57:10.750 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 9.071ms for cause HeapTrim
03-28 12:57:38.029 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.944ms
03-28 12:57:45.548 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.624ms
03-28 12:58:00.093 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.481ms
03-28 12:58:10.900 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 7.327ms for cause HeapTrim
03-28 12:59:42.489 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 7.841ms
03-28 13:00:01.148 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 6.726ms for cause HeapTrim
03-28 13:00:18.072 29897-29913/com.example.frances.rocksdrinks I/art: Background sticky concurrent mark sweep GC freed 26985(971KB) AllocSpace objects, 0(0B) LOS objects, 35% free, 1757KB/2MB, paused 6.471ms total 14.159ms
03-28 13:00:21.155 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 7.892ms for cause HeapTrim
03-28 13:00:41.162 29897-29912/com.example.frances.rocksdrinks I/art: WaitForGcToComplete blocked for 5.154ms for cause HeapTrim
03-28 13:02:48.702 29897-29908/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.836ms
03-28 13:02:53.694 29897-29913/com.example.frances.rocksdrinks W/art: Suspending all threads took: 5.996ms

我无法从我的代码中找出错误。这是目前应用中唯一的活动。谢谢。

更新: 我发现如果我删除了createAnswers函数,它会停止挂起,但我还没弄清楚它为什么会导致挂起。

解决: 事实证明,因为岩石饮料没有混音器(混音器hashmap中的所有条目都是空字符串),它会影响createAnswers中的else语句,我在其中为混音器问题创建答案。我不知道为什么它会造成内存泄漏,但我删除了它,现在它工作正常。

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

你应该检查createAnswers函数中的while循环,它是否每次都在可接受的时间结束或需要很长时间,因为count ++在一个可能无法满足的条件下