Получение NullPointerException при доступе к счетчику другого класса

101
15

У меня есть два класса " Settings и " MainActivity. Я пытаюсь получить доступ к счетчику, созданному в классе Settings из класса MainActivity.

Обычно это работает

public static Settings getlang = new Settings();

Проблема в том, что если я попытаюсь сделать это, не открыв сначала активность "Настройки" и напрямую перейдя в MainActivity, я получаю исключение NullPointerException на этой строке

getlang.getLang1().setSelection(getlang.getLang());

Но если я сначала открою активность Settings а затем MainActivity в MainActivity все будет хорошо.

Как я могу это исправить?

Вот активность Settings

public class Settings extends Activity {

public SharedPreferences prefsSet;
public String prefNameSet = "MyPrefSet";

public static final String PREFS_NAME_SET = "SAVEDATASET";

private static final String SPINNER1_STATE = "spinner1_state";

public int language;

public int userChoice;

private static Spinner spinner1;
private Button savesett;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);

savesett = (Button) findViewById(R.id.bSaveSett);

spinner1 = (Spinner) findViewById(R.id.spinner1);
SharedPreferences sharedPref = getSharedPreferences("FileName",
MODE_PRIVATE);
int spinnerValue = sharedPref.getInt("userChoiceSpinner", -1);
if (spinnerValue != -1)
// set the value of the spinner
spinner1.setSelection(spinnerValue);

spinner1.setOnItemSelectedListener(new OnItemSelectedListener() {

@Override
public void onItemSelected(AdapterView<?> parent, View view,
int pos, long id) {
// TODO Auto-generated method stub
userChoice = spinner1.getSelectedItemPosition();
SharedPreferences sharedPref = getSharedPreferences("FileName",
0);
SharedPreferences.Editor prefEditor = sharedPref.edit();
prefEditor.putInt("userChoiceSpinner", userChoice);
prefEditor.commit();
Toast.makeText(
parent.getContext(),
"Chosen Language: "
+ parent.getItemAtPosition(pos).toString(),
Toast.LENGTH_LONG).show();
}

@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub

}
});

savesett.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
Intent ourIntent = new Intent(Settings.this, MainActivity.class);
startActivity(ourIntent);
}

});
}

public int getLang() {

return userChoice;}

public Spinner getLang1() {

return Settings.spinner1;
}

}

спросил(а) 2013-10-14T06:55:00+04:00 7 лет назад
1
Решение
71

Из вашего кода я могу предположить (или, может быть, догадываться), что вы используете Spinner в файле Settings.class, чтобы выбрать язык пользователя, и вы также сохраняете его в SharedPreferences.xml.

Итак, вместо того, чтобы получать значение счетчика из объекта Spinner, просто прочитайте его из SharedPreferences.xml. Даже если вы этого не сделаете, я думаю, что это лучший способ подойти к вашей проблеме.

Теперь, когда вы открываете приложение в первый раз и что нет настроек, заданных для языка, вы можете установить значение по умолчанию (скажем, на английском языке). Когда пользователь меняет язык с помощью Spinner, вы можете сохранить его в SharedPreferences, а затем прочитать его с вашего MainActivity.class.

Код для работы с Shared Preferences:

-> Для записи данных в общие настройки:

SharedPreferences prefs = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();

// Saving Data to Shared Preferences
editor.putInt("userChoiceSpinner", 1);
editor.commit();

-> Для чтения данных из общих настроек:

SharedPreferences prefs = getPreferences(MODE_PRIVATE);
int spinner_value = prefs.getInt("userChoiceSpinner", -1); // Here -1 is the default value to return when there is no value for the key "userChoiceSpinner" in the Shared Preferences.

ответил(а) 2013-10-14T09:22:00+04:00 7 лет назад
41

Метод onCreate вызывается только тогда, когда эта конкретная активность запускается хотя бы один раз. Но поскольку вы даже не начинаете эту Settings, так что счетчик, который вы пытаетесь получить, не будет инициализирован, так как этот счетчик не найдет идентификатор, который вы даете findViewByid(id). Вот почему вы получаете исключение с нулевым указателем.


И когда вы получаете доступ к этому счетчику после запуска действия " Settings то счетчик может найти идентификатор, который он предоставляется, потому onCreate метод onCreate вызывается хотя бы один раз.

ответил(а) 2013-10-14T11:23:00+04:00 7 лет назад
41

Не следует создавать экземпляр класса активности

   public static Settings getlang = new Settings(); // wrong

Активность запускается startActivity с намерением. Активность имеет ui и жизненный цикл.

findviewById ищет представление с идентификатором в текущем раздутом макете. Поэтому, если вы пытаетесь инициализировать MainActivity который находится в Settings вы получаете NullPointerException.

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

Вы также можете использовать SharedPreferences

ответил(а) 2013-10-14T07:18:00+04:00 7 лет назад
41

Не создавая экземпляр Spinner, spinner1 = (Spinner) findViewById(R.id.spinner1); никогда не работает.

Вам нужно будет сделать что-то вроде этого:

Сделайте способ:

    public static void setSpinner(int id){
spinner=findViewById(id);
}

и запустите его заранее.

ответил(а) 2013-10-14T07:02:00+04:00 7 лет назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема