Почему мой код инициализации SplashActivity не выполняется?

В моем приложении есть некоторые глобальные/статические структуры данных, которые необходимо инициализировать перед отображением основного действия, поэтому я поместил работу в метод 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 не вызывается (верно?).

Я понятия не имею, как это воспроизвести, но это происходит довольно часто. Возможно, я оставил приложение в фоновом режиме и снова захожу. Но данные уровня приложения не должны быть выпущены, верно?

0
0
25
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Действия 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 необходимо будет повторно инициализировать.

Да, но когда приложение закрывается и пользователь возвращается, действия воссоздаются. onCreate следует вызывать.

NeoWang 13.06.2019 18:34

Конечно. Но если вы уже finish()-редактировали свою заставку, ее нет в стеке навигации и она не будет воссоздана.

Ben P. 13.06.2019 19:02

Почему бы просто не инициализировать их в классе 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 может очистить инициализированную переменную, если она не используется.

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

Какие ресурсы использует экземпляр класса?
Когда MEX-файл вызывается с использованием mexMakeMemoryPersistent, как переменным переназначаются их указатели при последующих вызовах?
Нужно ли вызывать нетривиальный деструктор, когда это noop?
Исчерпание памяти PHP, унаследованный код вызывает ошибку с большими файлами, нужно ли очищать память, выполнять пакетную обработку или увеличивать выделение памяти?
Понять поведение убийцы нехватки памяти
Как исправить проблему с утечкой памяти в коде Objective-C?
Выделить память для динамического массива структур внутри структуры с двойным указателем**
Глобально назначить UUID/уникальный идентификатор для каждого модуля для всех модулей
Исправлено выделение памяти для пользовательских типов в vba
Предлагает ли среда Apache Commons CSV инкрементный/последовательный режим с эффективным использованием памяти для чтения больших файлов?