问题
I have encountered two problems whenever this method with the switch statement was called:
sometimes (yes only sometimes, not everytime) when the variable
mDNumHit
has a value of 1, case 2 or case 3 was run instead of case 1.when
mDNumhit
is 1, it runs case 1. Now, let's saydCards3
is 9, case 9 has been run but only this portion of code
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard3.setImageResource(R.drawable.clubs9);
}
}, 500);
was run, and this
dTotal += 9;
dTotalAlt += 9;
did not (the variables were not updated).
Why is this happening? I just can't seem to figure out whats wrong.
The code:
public boolean dealerHit() {
final AnimationSet as = new AnimationSet(true);
as.addAnimation(animTranslate);
as.addAnimation(animSet);
final Random r = new Random();
//dealer hit
while ((dTotal < 17) && (dTotalAlt < 17) && ((mDNumHit + 2) < mMaxCards)) {
//update num of hit by dealer
mDNumHit++;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
cardSound.start();
switch (mDNumHit) {
case 1:
//create a random card
dCard3 = r.nextInt(52) + 1;
//dHitTemp = dCard3;
mImgDCard3.setVisibility(View.VISIBLE);
mImgDCard3.startAnimation(as);
switch (dCard3) {
case 1:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard3.setImageResource(R.drawable.clubs_a);
}
}, 500);
isDAce3 = true;
if (isDAce1 && isDAce2) {
dTotal = 3;
dTotalAlt = 13;
} else if (isDAce1 && !isDAce2) {
dTotalAlt = dTotal + 11;
dTotal += 1;
} else if (!isDAce1 && isDAce2) {
dTotalAlt = dTotal + 11;
dTotal += 1;
} else {
dTotal += 1;
dTotalAlt += 11;
}
break;
case 2:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard3.setImageResource(R.drawable.clubs2);
}
}, 500);
dTotal += 2;
dTotalAlt += 2;
break;
case 3:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard3.setImageResource(R.drawable.clubs3);
}
}, 500);
//img.setImageResource(R.drawable.clubs3);
dTotal += 3;
dTotalAlt += 3;
break;
case 4:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard3.setImageResource(R.drawable.clubs4);
}
}, 500);
dTotal += 4;
dTotalAlt += 4;
break;
case 5:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard3.setImageResource(R.drawable.clubs5);
}
}, 500);
dTotal += 5;
dTotalAlt += 5;
break;
case 6:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard3.setImageResource(R.drawable.clubs6);
}
}, 500);
dTotal += 6;
dTotalAlt += 6;
break;
case 7:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard3.setImageResource(R.drawable.clubs7);
}
}, 500);
dTotal += 7;
dTotalAlt += 7;
break;
case 8:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard3.setImageResource(R.drawable.clubs8);
}
}, 500);
dTotal += 8;
dTotalAlt += 8;
break;
case 9:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard3.setImageResource(R.drawable.clubs9);
}
}, 500);
dTotal += 9;
dTotalAlt += 9;
break;
case 10:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard3.setImageResource(R.drawable.clubs10);
}
}, 500);
dTotal += 10;
dTotalAlt += 10;
break;
case 11:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard3.setImageResource(R.drawable.clubs_j);
}
}, 500);
dTotal += 10;
dTotalAlt += 10;
break;
...other cases...
case 51:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard3.setImageResource(R.drawable.spades_q);
}
}, 500);
dTotal += 10;
dTotalAlt += 10;
break;
case 52:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard3.setImageResource(R.drawable.spades_k);
}
}, 500);
dTotal += 10;
dTotalAlt += 10;
break;
}
break;
case 2:
//create a random card
dCard4 = r.nextInt(52) + 1;
//dHitTemp = dCard4;
mImgDCard4.setVisibility(View.VISIBLE);
mImgDCard4.startAnimation(as);
switch (dCard4) {
case 1:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard4.setImageResource(R.drawable.clubs_a);
}
}, 500);
isDAce4 = true;
if ((isDAce1 && isDAce2) && isDAce3) {
dTotal = 4;
dTotalAlt = 14;
} else if (((isDAce1 && isDAce2) && !isDAce3) || ((isDAce1 && !isDAce2) && isDAce3) || ((!isDAce1 && isDAce2) && isDAce3)) {
dTotalAlt = dTotal + 11;
dTotal += 1;
} else if (((isDAce1 && !isDAce2) && !isDAce3) || ((!isDAce1 && isDAce2) && !isDAce3) || ((!isDAce1 && !isDAce2) && isDAce3)) {
dTotalAlt = dTotal + 11;
dTotal += 1;
} else {
dTotal += 1;
dTotalAlt += 11;
}
break;
case 2:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard4.setImageResource(R.drawable.clubs2);
}
}, 500);
//img.setImageResource(R.drawable.clubs2);
dTotal += 2;
dTotalAlt += 2;
break;
case 3:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard4.setImageResource(R.drawable.clubs3);
}
}, 500);
//img.setImageResource(R.drawable.clubs3);
dTotal += 3;
dTotalAlt += 3;
break;
case 4:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard4.setImageResource(R.drawable.clubs4);
}
}, 500);
//img.setImageResource(R.drawable.clubs4);
dTotal += 4;
dTotalAlt += 4;
break;
case 5:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard4.setImageResource(R.drawable.clubs5);
}
}, 500);
//img.setImageResource(R.drawable.clubs5);
dTotal += 5;
dTotalAlt += 5;
break;
case 6:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard4.setImageResource(R.drawable.clubs6);
}
}, 500);
//img.setImageResource(R.drawable.clubs6);
dTotal += 6;
dTotalAlt += 6;
break;
case 7:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard4.setImageResource(R.drawable.clubs7);
}
}, 500);
//img.setImageResource(R.drawable.clubs7);
dTotal += 7;
dTotalAlt += 7;
break;
case 8:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard4.setImageResource(R.drawable.clubs8);
}
}, 500);
//img.setImageResource(R.drawable.clubs8);
dTotal += 8;
dTotalAlt += 8;
break;
case 9:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard4.setImageResource(R.drawable.clubs9);
}
}, 500);
//img.setImageResource(R.drawable.clubs9);
dTotal += 9;
dTotalAlt += 9;
break;
case 10:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard4.setImageResource(R.drawable.clubs10);
}
}, 500);
//img.setImageResource(R.drawable.clubs10);
dTotal += 10;
dTotalAlt += 10;
break;
case 11:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard4.setImageResource(R.drawable.clubs_j);
}
}, 500);
//img.setImageResource(R.drawable.clubs_j);
dTotal += 10;
dTotalAlt += 10;
break;
....other cases...
case 51:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard4.setImageResource(R.drawable.spades_q);
}
}, 500);
//img.setImageResource(R.drawable.spades_q);
dTotal += 10;
dTotalAlt += 10;
break;
case 52:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard4.setImageResource(R.drawable.spades_k);
}
}, 500);
//img.setImageResource(R.drawable.spades_k);
dTotal += 10;
dTotalAlt += 10;
break;
}
break;
case 3:
//create a random card
dCard5 = r.nextInt(52) + 1;
//dHitTemp = dCard5;
mImgDCard5.setVisibility(View.VISIBLE);
mImgDCard5.startAnimation(as);
switch (dCard5) {
case 1:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard5.setImageResource(R.drawable.clubs_a);
}
}, 500);
isDAce5 = true;
if ((isDAce1 && isDAce2) && (isDAce3 && isDAce4)) {
dTotal = 5;
dTotalAlt = 15;
} else if ((!isDAce1 && !isDAce2) && (!isDAce3 && !isDAce4)) {
dTotal += 1;
dTotalAlt += 11;
} else {
dTotalAlt = dTotal + 11;
dTotal += 1;
}
break;
case 2:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard5.setImageResource(R.drawable.clubs2);
}
}, 500);
//img.setImageResource(R.drawable.clubs2);
dTotal += 2;
dTotalAlt += 2;
break;
case 3:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard5.setImageResource(R.drawable.clubs3);
}
}, 500);
//img.setImageResource(R.drawable.clubs3);
dTotal += 3;
dTotalAlt += 3;
break;
case 4:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard5.setImageResource(R.drawable.clubs4);
}
}, 500);
//img.setImageResource(R.drawable.clubs4);
dTotal += 4;
dTotalAlt += 4;
break;
case 5:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard5.setImageResource(R.drawable.clubs5);
}
}, 500);
//img.setImageResource(R.drawable.clubs5);
dTotal += 5;
dTotalAlt += 5;
break;
case 6:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard5.setImageResource(R.drawable.clubs6);
}
}, 500);
//img.setImageResource(R.drawable.clubs6);
dTotal += 6;
dTotalAlt += 6;
break;
case 7:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard5.setImageResource(R.drawable.clubs7);
}
}, 500);
//img.setImageResource(R.drawable.clubs7);
dTotal += 7;
dTotalAlt += 7;
break;
case 8:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard5.setImageResource(R.drawable.clubs8);
}
}, 500);
//img.setImageResource(R.drawable.clubs8);
dTotal += 8;
dTotalAlt += 8;
break;
case 9:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard5.setImageResource(R.drawable.clubs9);
}
}, 500);
//img.setImageResource(R.drawable.clubs9);
dTotal += 9;
dTotalAlt += 9;
break;
case 10:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard5.setImageResource(R.drawable.clubs10);
}
}, 500);
//img.setImageResource(R.drawable.clubs10);
dTotal += 10;
dTotalAlt += 10;
break;
case 11:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard5.setImageResource(R.drawable.clubs_j);
}
}, 500);
//img.setImageResource(R.drawable.clubs_j);
dTotal += 10;
dTotalAlt += 10;
break;
....other cases.....
case 52:
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mImgDCard5.setImageResource(R.drawable.spades_k);
}
}, 500);
//img.setImageResource(R.drawable.spades_k);
dTotal += 10;
dTotalAlt += 10;
break;
}
break;
}
//check if dealer burst or not (when hitting)
if (dTotal > 21) {//dealer burst
displayWin();
isBurst = true;
return; //exit from delay function
}
//flag dealer hit max card
if ((mDNumHit + 2) == mMaxCards) {
isDealerMax = true;
} else {
isDealerMax = false;
}
}
}, 1500); //end delay function
} //end while loop
if (isBurst) {
return true;
} else {
return false;
}
}
回答1:
mDNumHit
is a field, and yet, you are creating a handler with a runnable - that strongly suggests multiple threads.
So, what's happening is that one thread is changing mDNumHit before you get to that switch. The fix is not to use fields for this, pass to your handler the value of mDNumHit.
It's a bit like having one global whiteboard where, every time there's a new sale, someone runs up, wipes out the number that is there, and writes down the next number.
Imagine the folks who are packing the order into a box are instructed to always look at the whiteboard, every time, and then look up the order. This is going to go completely wrong, when someone changes the number halfway through packing.
The fix is to tell them not to look at the whiteboard at all - pass them the order number they need to pack and tell them only to look at that.
来源:https://stackoverflow.com/questions/64979378/switch-statements-going-to-wrong-case-and-other-problems