-1

I have been trying to fix a bug in my application for already 3 days, with no success. The problem is that an instance variable gets magically assigned.

The application is a bluetooth multiplayer game in which the players take turn. After the game is over a dialog is shown to ask the players if they would like to continue. So when the player 1 continues, a message is sent to player 2 to notify that player 1 wants continue. The variable "opponentContinued" gets true. And when the player 2 clicks continue too, if opponentContinued equals true the game restarts.

The problem :

When the dialog is shown to both of the players and player 1 rotates the screen, player 2 clicks continue, player 1 receives notification and "opponentContinued" gets assigned as true. AFTER this when player 1 clicks continue and (opponentContinued must be true) checks if "opponentContinued" is true, finds that "opponentContinued" is false.

Everything works fine if there is no rotation.

Then to make it a bit clear I made a dummy variable to monitor when and how "opponentContinued" gets assigned and every time it got assigned I made dummyBoolean equal to "opponentContinued". I made dummyBoolean true as default. In "onContinueClicked" methods "dummyBoolean" is true, while "opponentContinued" is false.

public class MainActivity extends Activity {

    private boolean opponentContinued;
    private boolean dummyBoolean = true;



    private void onOpponentContinued(){
        opponentContinued = true;
        dummyBoolean = opponentContinued;
    }

    private void onContinueClicked(){
        // opponentContinued is false
        // dummyBoolean is true
        if (opponentContinued){
              // Continue the game
        }
    }
}

I have no idea what could be the problem. Have anyone experienced a problem like this? Any help is appreciated.

EDIT

Please note that the problem has to do nothing with saving states during screen rotation. The problem is that the variable "opponentContined" is "magically" assigned to the default value false, after it is set to true.

I know this sounds unrealistic but it has ruined me a lot of time.

Nika Kurdadze
  • 2,314
  • 3
  • 15
  • 25
  • you should save the state of your variables when onPause is called (rotation, click home button, etc...) – PedroHawk Mar 22 '16 at 16:13
  • The problem is not about about the states. I don't need to save anything. – Nika Kurdadze Mar 22 '16 at 16:14
  • I have to say that PedroHawk is right....check this link http://stackoverflow.com/questions/10126845/handle-screen-rotation-without-losing-data-android – Miguel Benitez Mar 22 '16 at 16:19
  • @NikaKurdadze What makes you say that? Device rotation kills and recreates the Activity so you most definitely do need to save the state. – DeeV Mar 22 '16 at 16:19
  • I know and I am saving and retrieving information that I need to run the game properly, but this particular problem has nothing with screen rotation. The problem is that the assigned variable (opponentContinued = true) is then magically assigned to its default value false. – Nika Kurdadze Mar 22 '16 at 16:26
  • You have not written here all code working with this variable. – Gangnus Mar 22 '16 at 20:47

3 Answers3

2

https://developer.android.com/guide/topics/resources/runtime-changes.html

Some device configurations can change during runtime (such as screen orientation, keyboard availability, and language). When such a change occurs, Android restarts the running Activity (onDestroy() is called, followed by onCreate()). The restart behavior is designed to help your application adapt to new configurations by automatically reloading your application with alternative resources that match the new device configuration.

To properly handle a restart, it is important that your activity restores its previous state through the normal Activity lifecycle, in which Android calls onSaveInstanceState() before it destroys your activity so that you can save data about the application state. You can then restore the state during onCreate() or onRestoreInstanceState()

Your problem is that when the user rotates the device, your activity object is destroyed and a new one is created in its place. Thus the values are (re-)initialized during the creation of the new instance. You need to save the state and then restore it when the device is rotated.

Community
  • 1
  • 1
dsh
  • 11,380
  • 3
  • 27
  • 48
  • There's no magic. Java initializes variables (unlike C), and booleans are initialized to false. On rotation your object goes away, and a new instance of your activity is created. Thus the field is assigned an initial value of false. You can prove this by using the debugger and setting a breakpoint on the field's access. Also, you can add onSaveInstanceState(), onRestoreInstanceState(), onDestroy(), onCreate(), and onResume() methods and a constructor to log when the various parts of the activity lifecycle occur. Then you'll be able to see that your activity is destroyed and recreated. – dsh Mar 22 '16 at 17:13
  • I know that and that's not the problem. When I rotate the screen the activity gets recreated, then the boolean variable is initialized to initial value. After that player 2 continues and player 1 receives a message to set the value to true. The value is set to true. Then when the player 1 continues and checks if the value is true, but finds that it is false. – Nika Kurdadze Mar 22 '16 at 17:31
  • The code you posted doesn't demonstrate that. The code you posted demonstrates the problem at least 5 of us are describing. You also said that the problem only occurs when a device is rotated. Use your debugger to watch when the field is assigned to discover when its value changes. Or post a [MCVE](https://stackoverflow.com/help/mcve) if you want others to be able to reproduce the problem and help solve it. – dsh Mar 22 '16 at 17:56
  • 1
    Here's another thing you can observer: change your field from `boolean` to `Boolean`. Then it will be `null` when the VM initializes it rather than `false`. When a NullPointerException is raised you will know that your code did not assign a true or a false value. – dsh Mar 22 '16 at 17:59
  • I will add that this question is essentially the same as your earlier question [When do activity's instance variables get initialized?](http://stackoverflow.com/q/36153344/1172714). – dsh Mar 22 '16 at 18:04
0

When you are checking if the opponent continued, you should at first ask for a variable content. If opponentContinued is false, repeat the question to the opponent's device.

Gangnus
  • 22,127
  • 14
  • 79
  • 132
0

Default value of boolean in java is false since variable is being recreated assigned by default value false

The problem is Activity is getting recreated on screen orientation changed.you can solve this by 3 ways

1.you can make use of onSaveInstanceState and onRestoreInstanceState to save and retrieve boolean value

2.make your boolean variable static and declare it outside lifecycle methods

3.use shared preferences to keep track of your boolean variable

vignesh karnika
  • 101
  • 1
  • 5