信号灯崩溃 android 应用
Semaphore crashes android app
作为高中时试图为 Comp Sci 制作一个快速简单的 android 应用程序的初学者,我一直在努力将一个功能性的冒险风格游戏移植到 android 5.1.1。你在两个按钮之间做出选择,穿过一座令人毛骨悚然的老房子,你的选择会影响结果。我采用的方法是使用带有 switch 语句的 do 循环,使用信号量等待选择。使用信号量似乎使我的应用程序崩溃:Logcat 未显示任何错误,但是当我在开始时放置调试选项,甚至在使用开关功能之前,应用程序在尝试获取信号量时崩溃。注释掉信号量解决了问题。
tl;dr 在 android 上处理双按钮选择的更合适方法是什么?
代码如下:
冒险游戏的主要部分
public static Button btnYes, btnNo;
public static TextView textField;
public static Semaphore semaphore = new Semaphore(0);
public static String btnUsed = "";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_adventure);
btnYes = (Button) findViewById(R.id.buttonYes);
btnNo = (Button) findViewById(R.id.buttonNo);
textField = (TextView) findViewById(R.id.textFieldText);
textField.setText("Debug Screen! Begin?");
btnYes.setText("Yes");
btnNo.setText("No");
try {
semaphore.acquire();
Switch();
} catch (InterruptedException e) {
}
}
public void btnYesClicked(View v) {
btnUsed = Prompts.yes;
semaphore.release();
}
public void btnNoClicked(View v) {
btnUsed = Prompts.no;
semaphore.release();
}
public static void Switch() throws InterruptedException {
boolean isRunning = true;
String place = Prompts.doorway;
String choice = "";
do {
switch (place) {
case Prompts.doorway:
semaphore.drainPermits();
textField.setText(Prompts.doorwayPrompt);
btnYes.setText(Prompts.kitchen);
btnNo.setText(Prompts.upstairs);
semaphore.acquire();
choice = btnUsed;
if (choice.equals(Prompts.yes) || choice.equals(Prompts.no)) {
if (choice.equals(Prompts.yes)) {
place = Prompts.kitchen;
} else {
place = Prompts.upstairs;
}
} else {
place = "default";
}
break;
case Prompts.kitchen:
semaphore.drainPermits();
textField.setText(Prompts.kitchenPrompt);
btnYes.setText(Prompts.fridge);
btnNo.setText(Prompts.cabinet);
semaphore.acquire();
choice = btnUsed;
if (choice.equals(Prompts.yes) || choice.equals(Prompts.no)) {
if (choice.equals(Prompts.yes)) {
place = Prompts.fridge;
} else {
place = Prompts.cabinet;
}
} else {
place = "default";
}
break;
case Prompts.upstairs:
semaphore.drainPermits();
textField.setText(Prompts.upstairsPrompt);
btnYes.setText(Prompts.bedroom);
btnNo.setText(Prompts.bathroom);
semaphore.acquire();
choice = btnUsed;
if (choice.equals(Prompts.yes) || choice.equals(Prompts.no)) {
if (choice.equals(Prompts.yes)) {
place = Prompts.bedroom;
} else {
place = Prompts.bathroom;
}
} else {
place = "default";
}
break;
case Prompts.fridge:
semaphore.drainPermits();
textField.setText(Prompts.fridgePrompt);
btnYes.setText(Prompts.yes);
btnNo.setText(Prompts.no);
semaphore.acquire();
choice = btnUsed;
if (choice.equals(Prompts.yes) || choice.equals(Prompts.no)) {
if (choice.equals(Prompts.yes)) {
textField.setText(Prompts.fridgeYes);
place = "done";
} else {
textField.setText(Prompts.fridgeNo);
place = "done";
}
}
break;
case Prompts.cabinet:
semaphore.drainPermits();
textField.setText(Prompts.cabinetPrompt);
btnYes.setText(Prompts.yes);
btnNo.setText(Prompts.no);
semaphore.acquire();
choice = btnUsed;
if (choice.equals(Prompts.yes) || choice.equals(Prompts.no)) {
if (choice.equals(Prompts.yes)) {
textField.setText(Prompts.cabinetYes);
place = "done";
} else {
textField.setText(Prompts.cabinetNo);
place = "done";
}
}
break;
case Prompts.bedroom:
semaphore.drainPermits();
textField.setText(Prompts.bedroomPrompt);
btnYes.setText(Prompts.yes);
btnNo.setText(Prompts.no);
semaphore.acquire();
choice = btnUsed;
if (choice.equals(Prompts.yes) || choice.equals(Prompts.no)) {
if (choice.equals(Prompts.yes)) {
textField.setText(Prompts.bedroomYes);
place = "done";
} else {
textField.setText(Prompts.bedroomNo);
place = "done";
}
}
break;
case Prompts.bathroom:
semaphore.drainPermits();
textField.setText(Prompts.bathroomPrompt);
btnYes.setText(Prompts.yes);
btnNo.setText(Prompts.no);
semaphore.acquire();
choice = btnUsed;
if (choice.equals(Prompts.yes) || choice.equals(Prompts.no)) {
if (choice.equals(Prompts.yes)) {
textField.setText(Prompts.bathroomYes);
place = "done";
} else {
textField.setText(Prompts.bathroomNo);
place = "done";
}
}
break;
case "done":
semaphore.drainPermits();
btnYes.setText("Again");
btnNo.setText("Finish");
semaphore.acquire();
choice = btnUsed;
if (choice.equals(Prompts.yes) || choice.equals(Prompts.no)) {
if (choice.equals(Prompts.yes)) {
place = Prompts.doorway;
} else {
isRunning = false;
}
}
default:
textField.setText("Not a valid answer!");
break;
}
} while (isRunning);
}
Activity 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"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".Adventure">
<TextView android:text="@string/app_name"
android:layout_width="wrap_content"
android:id="@+id/textFieldText"
android:layout_height="wrap_content"
android:layout_marginTop="73dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/yes"
android:id="@+id/buttonYes"
android:layout_alignTop="@+id/buttonNo"
android:onClick="btnYesClicked"
android:layout_alignParentStart="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/no"
android:id="@+id/buttonNo"
android:layout_centerVertical="true"
android:onClick="btnNoClicked"
android:layout_alignParentEnd="true" />
</RelativeLayout>
如评论中所述,您正在屏蔽 UI。更好的处理方法是将 String place
存储在字段变量中(就像您使用的按钮一样)。更改您的 Switch()
方法以接受选择参数 Switch(String choice)
并消除 do/while 然后更改您的 btnYesClicked
和 btnNoClicked
以调用 Switch 方法并传递正确的按钮。
作为高中时试图为 Comp Sci 制作一个快速简单的 android 应用程序的初学者,我一直在努力将一个功能性的冒险风格游戏移植到 android 5.1.1。你在两个按钮之间做出选择,穿过一座令人毛骨悚然的老房子,你的选择会影响结果。我采用的方法是使用带有 switch 语句的 do 循环,使用信号量等待选择。使用信号量似乎使我的应用程序崩溃:Logcat 未显示任何错误,但是当我在开始时放置调试选项,甚至在使用开关功能之前,应用程序在尝试获取信号量时崩溃。注释掉信号量解决了问题。
tl;dr 在 android 上处理双按钮选择的更合适方法是什么?
代码如下:
冒险游戏的主要部分
public static Button btnYes, btnNo;
public static TextView textField;
public static Semaphore semaphore = new Semaphore(0);
public static String btnUsed = "";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_adventure);
btnYes = (Button) findViewById(R.id.buttonYes);
btnNo = (Button) findViewById(R.id.buttonNo);
textField = (TextView) findViewById(R.id.textFieldText);
textField.setText("Debug Screen! Begin?");
btnYes.setText("Yes");
btnNo.setText("No");
try {
semaphore.acquire();
Switch();
} catch (InterruptedException e) {
}
}
public void btnYesClicked(View v) {
btnUsed = Prompts.yes;
semaphore.release();
}
public void btnNoClicked(View v) {
btnUsed = Prompts.no;
semaphore.release();
}
public static void Switch() throws InterruptedException {
boolean isRunning = true;
String place = Prompts.doorway;
String choice = "";
do {
switch (place) {
case Prompts.doorway:
semaphore.drainPermits();
textField.setText(Prompts.doorwayPrompt);
btnYes.setText(Prompts.kitchen);
btnNo.setText(Prompts.upstairs);
semaphore.acquire();
choice = btnUsed;
if (choice.equals(Prompts.yes) || choice.equals(Prompts.no)) {
if (choice.equals(Prompts.yes)) {
place = Prompts.kitchen;
} else {
place = Prompts.upstairs;
}
} else {
place = "default";
}
break;
case Prompts.kitchen:
semaphore.drainPermits();
textField.setText(Prompts.kitchenPrompt);
btnYes.setText(Prompts.fridge);
btnNo.setText(Prompts.cabinet);
semaphore.acquire();
choice = btnUsed;
if (choice.equals(Prompts.yes) || choice.equals(Prompts.no)) {
if (choice.equals(Prompts.yes)) {
place = Prompts.fridge;
} else {
place = Prompts.cabinet;
}
} else {
place = "default";
}
break;
case Prompts.upstairs:
semaphore.drainPermits();
textField.setText(Prompts.upstairsPrompt);
btnYes.setText(Prompts.bedroom);
btnNo.setText(Prompts.bathroom);
semaphore.acquire();
choice = btnUsed;
if (choice.equals(Prompts.yes) || choice.equals(Prompts.no)) {
if (choice.equals(Prompts.yes)) {
place = Prompts.bedroom;
} else {
place = Prompts.bathroom;
}
} else {
place = "default";
}
break;
case Prompts.fridge:
semaphore.drainPermits();
textField.setText(Prompts.fridgePrompt);
btnYes.setText(Prompts.yes);
btnNo.setText(Prompts.no);
semaphore.acquire();
choice = btnUsed;
if (choice.equals(Prompts.yes) || choice.equals(Prompts.no)) {
if (choice.equals(Prompts.yes)) {
textField.setText(Prompts.fridgeYes);
place = "done";
} else {
textField.setText(Prompts.fridgeNo);
place = "done";
}
}
break;
case Prompts.cabinet:
semaphore.drainPermits();
textField.setText(Prompts.cabinetPrompt);
btnYes.setText(Prompts.yes);
btnNo.setText(Prompts.no);
semaphore.acquire();
choice = btnUsed;
if (choice.equals(Prompts.yes) || choice.equals(Prompts.no)) {
if (choice.equals(Prompts.yes)) {
textField.setText(Prompts.cabinetYes);
place = "done";
} else {
textField.setText(Prompts.cabinetNo);
place = "done";
}
}
break;
case Prompts.bedroom:
semaphore.drainPermits();
textField.setText(Prompts.bedroomPrompt);
btnYes.setText(Prompts.yes);
btnNo.setText(Prompts.no);
semaphore.acquire();
choice = btnUsed;
if (choice.equals(Prompts.yes) || choice.equals(Prompts.no)) {
if (choice.equals(Prompts.yes)) {
textField.setText(Prompts.bedroomYes);
place = "done";
} else {
textField.setText(Prompts.bedroomNo);
place = "done";
}
}
break;
case Prompts.bathroom:
semaphore.drainPermits();
textField.setText(Prompts.bathroomPrompt);
btnYes.setText(Prompts.yes);
btnNo.setText(Prompts.no);
semaphore.acquire();
choice = btnUsed;
if (choice.equals(Prompts.yes) || choice.equals(Prompts.no)) {
if (choice.equals(Prompts.yes)) {
textField.setText(Prompts.bathroomYes);
place = "done";
} else {
textField.setText(Prompts.bathroomNo);
place = "done";
}
}
break;
case "done":
semaphore.drainPermits();
btnYes.setText("Again");
btnNo.setText("Finish");
semaphore.acquire();
choice = btnUsed;
if (choice.equals(Prompts.yes) || choice.equals(Prompts.no)) {
if (choice.equals(Prompts.yes)) {
place = Prompts.doorway;
} else {
isRunning = false;
}
}
default:
textField.setText("Not a valid answer!");
break;
}
} while (isRunning);
}
Activity 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"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".Adventure">
<TextView android:text="@string/app_name"
android:layout_width="wrap_content"
android:id="@+id/textFieldText"
android:layout_height="wrap_content"
android:layout_marginTop="73dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/yes"
android:id="@+id/buttonYes"
android:layout_alignTop="@+id/buttonNo"
android:onClick="btnYesClicked"
android:layout_alignParentStart="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/no"
android:id="@+id/buttonNo"
android:layout_centerVertical="true"
android:onClick="btnNoClicked"
android:layout_alignParentEnd="true" />
</RelativeLayout>
如评论中所述,您正在屏蔽 UI。更好的处理方法是将 String place
存储在字段变量中(就像您使用的按钮一样)。更改您的 Switch()
方法以接受选择参数 Switch(String choice)
并消除 do/while 然后更改您的 btnYesClicked
和 btnNoClicked
以调用 Switch 方法并传递正确的按钮。