NullPointerException в onResume при изменении кнопок, почему?

Я получаю исключение NullPointerException от ряда моих пользователей, и я не могу определить, в чем проблема, оно отображается в этой строке:

((Button)findViewById(R.id.speakEnglishButton)).setText("");

Я не вижу, что не так, кнопка с этим идентификатором существует, она отлично компилируется, отлично работает на моем эмуляторе и на двух устройствах, однако я получаю около 100 или около того сообщений об ошибках в консоли разработчика для пользователей на этом версия.

Присмотревшись к onResume:

@Override
protected void onResume()
{
    super.onResume();

    SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
    boolean isButtonLabelsEnabled = sp.getBoolean("isButtonLabelsEnabled", false);
    if (!isButtonLabelsEnabled)
    {
        ((Button)findViewById(R.id.speakEnglishButton)).setText("");
        ((Button)findViewById(R.id.speakFrenchButton)).setText("");
        ((Button)findViewById(R.id.speakSpanishButton)).setText("");
        ((Button)findViewById(R.id.speakGermanButton)).setText("");
        ((Button)findViewById(R.id.speakItalianButton)).setText("");
    }
    else
    {
        ((Button)findViewById(R.id.speakEnglishButton)).setText(getString(R.string.btnLblEnglish));
        ((Button)findViewById(R.id.speakFrenchButton)).setText(getString(R.string.btnLblFrench));
        ((Button)findViewById(R.id.speakSpanishButton)).setText(getString(R.string.btnLblSpanish));
        ((Button)findViewById(R.id.speakGermanButton)).setText(getString(R.string.btnLblGerman));
        ((Button)findViewById(R.id.speakItalianButton)).setText(getString(R.string.btnLblItalian));
    }
}

По сути, все, что я делаю, - это проверяю сохраненное предпочтение логическое, и в зависимости от его значения я либо устанавливаю метки на кнопках, либо задаю их для пробелов.

Может кто-нибудь, пожалуйста, посоветуйте?

Спасибо

4 ответа

Решение

Сделайте все это ((кнопка)findViewById(R.id.speakEnglishButton)). SetText(""); .... в onCreate()

добавлять

private Button mSpeakEngButton;
.....

Как переменные класса, инициализируйте их в onCreate()

public void onCreate() {

   ....
   mSpeakEngButton = ((Button)findViewById(R.id.speakEnglishButton));
}

Позже в коде вы можете изменить их значения как mSpeakEngButton.setWhothing ()

Я думаю, что дело в том, что когда пользователь возобновляет деятельность, макет не устанавливается и, следовательно, findViewById() не имеет "якоря" для поиска и, следовательно, возвращает ноль.

Вы можете просто переместить звонок на setContentView() от onCreate в onResume (учитывая, что вы не ссылаетесь на мнения в onCreate, Для обычного использования это не имеет значения, как в жизненном цикле Android, onResumeнапрямую вызывается после onCreate и прежде чем пользователь сможет взаимодействовать с деятельностью.

На самом деле в некоторых приложениях есть ошибка, когда вы посещаете мероприятие, затем запускаете другое, возможно, оставляете приложение для другого, возвращаетесь, а затем возвращаетесь (с помощью кнопки назад) к первому действию. Здесь вдруг вы видите черный экран. Это связано с тем, что система "поменяла" первое действие и только при возврате onResume называется, но не onCreate, поэтому нет возможности снова загрузить макет туда.

Скорее всего, это вызвано, когда

((Button)findViewById(R.id.speakEnglishButton));

возвращает ноль. Это происходит, если такой ресурс не может быть найден. Спонтанно мне в голову приходит одна причина: у вас нет ресурсов по умолчанию в вашем макете. Это означает: у вас должен быть хотя бы один макет "по умолчанию", который применяется для каждого языка / ориентации /..., который должен быть помещен в папку "макет". Просто "макет".

Если вы сохраните setContentView() в onResume() вместо onCreate(), это даст исключение надувать, я пробовал это.

Другие вопросы по тегам