Переменная экземпляра волшебным образом назначается в Java

Я уже 3 дня безуспешно пытаюсь исправить ошибку в своем приложении. Проблема в том, что переменная экземпляра назначается волшебным образом.

Приложение представляет собой многопользовательскую игру по Bluetooth, в которой игроки по очереди. По окончании игры отображается диалоговое окно с вопросом о продолжении игры. Поэтому, когда игрок 1 продолжает, игроку 2 отправляется сообщение, чтобы уведомить, что игрок 1 хочет продолжить. Переменная противникаContinued становится истинной. И когда игрок 2 щелкает "Продолжить", если оппонентContinued равен true, игра перезапускается.

Эта проблема :

Когда диалог показан обоим игрокам и игрок 1 поворачивает экран, игрок 2 нажимает кнопку «Продолжить», игрок 1 получает уведомление, и «оппонентпродолжен» присваивается значение «истина». ПОСЛЕ этого, когда игрок 1 нажимает кнопку «Продолжить» и (оппонентContinued должен быть истинным) проверяет, истинно ли «оппонентконтинуед», обнаруживает, что «оппонентконтинуедед» ложно.

Все нормально работает, если нет вращения.

Затем, чтобы прояснить ситуацию, я сделал фиктивную переменную, чтобы отслеживать, когда и как назначается «оппонентContinued», и каждый раз, когда она назначается, я делал dummyBoolean равным «оппоненту». Я сделал dummyBoolean истинным по умолчанию. В методах onContinueClicked значение dummyBoolean истинно, а оппонентContinued - ложно.

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
        }
    }
}

Понятия не имею, в чем может быть проблема. Кто-нибудь сталкивался с такой проблемой? Любая помощь приветствуется.

ИЗМЕНИТЬ

Обратите внимание, что проблема не связана с сохранением состояний во время поворота экрана. Проблема в том, что переменной «оппонентContined» «волшебным образом» присваивается значение по умолчанию false после того, как оно установлено в true.

Я знаю, что это звучит нереально, но это испортило мне много времени.


person Nika Kurdadze    schedule 22.03.2016    source источник
comment
вы должны сохранить состояние ваших переменных при вызове onPause (вращение, нажатие кнопки домой и т. д.)   -  person PedroHawk    schedule 22.03.2016
comment
Проблема не в штатах. Мне ничего не нужно экономить.   -  person Nika Kurdadze    schedule 22.03.2016
comment
Я должен сказать, что ПедроХок прав .... проверьте эту ссылку stackoverflow.com/questions/10126845/   -  person Miguel Benitez    schedule 22.03.2016
comment
@NikaKurdadze Почему ты так говоришь? Вращение устройства уничтожает и воссоздает Activity, поэтому вам определенно нужно сохранить состояние.   -  person DeeV    schedule 22.03.2016
comment
Я знаю, и я сохраняю и извлекаю информацию, которая мне нужна для правильного запуска игры, но эта конкретная проблема не связана с поворотом экрана. Проблема в том, что присвоенной переменной (оппонентContinued = true) волшебным образом присваивается значение по умолчанию false.   -  person Nika Kurdadze    schedule 22.03.2016
comment
Вы не написали здесь весь код, работающий с этой переменной.   -  person Gangnus    schedule 22.03.2016


Ответы (3)


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

Некоторые конфигурации устройства могут изменяться во время работы (например, ориентация экрана, доступность клавиатуры и язык). Когда происходит такое изменение, Android перезапускает запущенную Activity (вызывается onDestroy (), а затем onCreate ()). Поведение при перезапуске призвано помочь вашему приложению адаптироваться к новым конфигурациям путем автоматической перезагрузки приложения с использованием альтернативных ресурсов, соответствующих новой конфигурации устройства.

Чтобы правильно обработать перезапуск, важно, чтобы ваша активность восстанавливала свое предыдущее состояние в течение обычного жизненного цикла Activity, в котором Android вызывает onSaveInstanceState (), прежде чем он уничтожит вашу активность, чтобы вы могли сохранить данные о состоянии приложения. Затем вы можете восстановить состояние во время onCreate () или onRestoreInstanceState ()

Ваша проблема в том, что когда пользователь поворачивает устройство, ваш объект действия уничтожается, а на его месте создается новый. Таким образом, значения инициализируются (повторно) во время создания нового экземпляра. Вам нужно сохранить состояние, а затем восстановить его при повороте устройства.

person dsh    schedule 22.03.2016
comment
Никакой магии. Java инициализирует переменные (в отличие от C), а логические значения инициализируются значением false. При вращении ваш объект уходит, и создается новый экземпляр вашего действия. Таким образом, полю присваивается начальное значение false. Вы можете доказать это, используя отладчик и установив точку останова на доступе к полю. Кроме того, вы можете добавить методы onSaveInstanceState (), onRestoreInstanceState (), onDestroy (), onCreate () и onResume () и конструктор для регистрации, когда происходят различные части жизненного цикла активности. Тогда вы увидите, что ваша деятельность уничтожена и воссоздана. - person dsh; 22.03.2016
comment
Я знаю это, и проблема не в этом. Когда я поворачиваю экран, действие воссоздается, а затем логическая переменная инициализируется начальным значением. После этого игрок 2 продолжает, и игрок 1 получает сообщение, чтобы установить значение true. Установлено значение true. Затем, когда игрок 1 продолжает и проверяет, истинно ли значение, но обнаруживает, что оно ложно. - person Nika Kurdadze; 22.03.2016
comment
Опубликованный вами код этого не демонстрирует. Опубликованный вами код демонстрирует проблему, которую описывают как минимум 5 из нас. Вы также сказали, что проблема возникает только при повороте устройства. Используйте отладчик, чтобы следить за назначением поля, чтобы узнать, когда его значение изменяется. Или опубликуйте MCVE, если хотите, чтобы другие могли воспроизвести проблему и помочь в ее решении. - person dsh; 22.03.2016
comment
Вот еще одна вещь, которую вы можете наблюдать: измените свое поле с boolean на Boolean. Тогда это будет null, когда виртуальная машина инициализирует его, а не false. Когда возникает исключение NullPointerException, вы будете знать, что ваш код не присвоил истинное или ложное значение. - person dsh; 22.03.2016
comment
Я добавлю, что этот вопрос по сути совпадает с вашим предыдущим вопросом Когда инициализируются переменные экземпляра активности?. - person dsh; 22.03.2016

Когда вы проверяете, продолжил ли оппонент, вы должны сначала попросить переменное содержание. Если opponentContinued ложно, повторите вопрос на устройство оппонента.

person Gangnus    schedule 22.03.2016

Значение логического значения по умолчанию в java - false, так как переменная воссоздается, присвоено значение по умолчанию false.

Проблема в том, что Activity воссоздается при изменении ориентации экрана. Вы можете решить эту проблему тремя способами.

1. вы можете использовать onSaveInstanceState и onRestoreInstanceState для сохранения и получения логического значения

2. сделать вашу логическую переменную статической и объявить ее вне методов жизненного цикла

3. используйте общие настройки, чтобы отслеживать вашу логическую переменную

person vignesh karnika    schedule 22.03.2016