В моем приложении есть некоторые глобальные/статические структуры данных, которые необходимо инициализировать перед отображением основного действия, поэтому я поместил работу в метод onCreate моего SplashActivity, который просто показывает заставку в течение 2 секунд, запускает другое действие и завершает себя:
initializeGlobalData();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent i = new Intent(SplashActivity.this, MainActivity.class);
startActivity(i);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
finish();
}
}, 2000);
Теперь мое приложение иногда загадочно падает из-за ссылки на нулевой указатель - некоторые глобальные структуры данных не инициализированы. Это может означать только то, что метод onCreate SplashActivity не вызывается (верно?).
Я понятия не имею, как это воспроизвести, но это происходит довольно часто. Возможно, я оставил приложение в фоновом режиме и снова захожу. Но данные уровня приложения не должны быть выпущены, верно?
Действия Splash по своей природе недолговечны, и на них не следует полагаться для каких-либо глобальных структур данных. Если вам это нужно, вам нужно создать класс Application и выполнить всю инициализацию вашей глобальной структуры данных там. Они не выйдут за рамки на протяжении всего срока службы приложения.
It's possible I left the app in the background, and re-enter. But application level data should not be released, right?
Это зависит от того, что вы имеете в виду, когда говорите «глобальные/статические структуры данных, которые необходимо инициализировать».
Если пользователь покидает ваше приложение, ожидается, что ОС Android может завершить процесс вашего приложения. Когда это произойдет, все, что хранится только в памяти, будет потеряно.
Типичным примером является, например. некоторое значение public static, которое вы загружаете один раз, а затем ссылаетесь на него во всем приложении. Когда ОС завершает процесс вашего приложения, а затем пользователь возвращается в ваше приложение, это значение public static необходимо будет повторно инициализировать.
Конечно. Но если вы уже finish()-редактировали свою заставку, ее нет в стеке навигации и она не будет воссоздана.
Почему бы просто не инициализировать их в классе Application
public class MyApplication extends Application {
private int globalData = 0;
public int getGlobalData() {
return globalData;
}
public void setGlobalData(int globalData) {
this.globalData = globalData ;
}
@Override
public void onCreate() {
super.onCreate();
setGlobalData(100)
}
}
Измените тег приложения в файле манифеста-
<application
android:allowBackup = "true"
android:icon = "@mipmap/ic_launcher"
android:label = "@string/app_name"
android:name = ".MyApplication" . // declare the application class
android:roundIcon = "@mipmap/ic_launcher_round"
android:supportsRtl = "true"
android:theme = "@style/AppTheme">
Теперь вы можете получить доступ к этому в любом месте приложения, например
((MyApplication) getApplicationContext()).getGlobalData()
Поведение, которое у вас есть, связано с тем, что если приложение находится в фоновом режиме, даже если оно не было закрыто, ОС Android может очистить инициализированную переменную, если она не используется.
Да, но когда приложение закрывается и пользователь возвращается, действия воссоздаются.
onCreateследует вызывать.