Android, метод вызова в потоке пользовательского интерфейса после перезапуска Действия из-за изменения конфигурации (поворот устройства) ничего не делает

СИТУАЦИЯ:

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

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Installer.installApkData(this);

    simulator = new Simulator(this);
    MainActivity prevActivity = (MainActivity)getLastCustomNonConfigurationInstance();
   if(prevActivity!= null) { 
       // So the orientation did change
       // Restore some field for example
       this.simulator = prevActivity.simulator;
       //this.mNavigationDrawerFragment = prevActivity.mNavigationDrawerFragment;
       //this.mTitle = prevActivity.mTitle;
       Log.d("APP","Activity restarted: simulator recreated");
   }

    requestWindowFeature(Window.FEATURE_PROGRESS);
    setContentView(R.layout.activity_main);
    setProgressBarVisibility(true);

    mNavigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager()
            .findFragmentById(R.id.navigation_drawer);
    mTitle = getTitle();

    // Set up the drawer.
    mNavigationDrawerFragment.setUp(R.id.navigation_drawer,
            (DrawerLayout) findViewById(R.id.drawer_layout));

}


@Override
public Object onRetainCustomNonConfigurationInstance() {
    //restore all your data here
    return this;
}
...

В действии есть метод, который изменяет выбранный раздел в NavigationDrawer в потоке пользовательского интерфейса, потому что в противном случае происходит сбой.

public void showHud() {
    // TODO Auto-generated method stub
    runOnUiThread( new Runnable() {
        public void run() {
            mNavigationDrawerFragment.select(1);
            onSectionAttached(2);
            restoreActionBar();
        }
    });
}

Этот метод используется для прямого перехода к отображению моделирования после подключения симулятора.

ПРОБЛЕМА:

Вся эта система работает кроме того случая, когда я подключаю тренажер после переключения ориентации. Он выполняет runOnUiThread, но ничего не делает. Я думаю, причина этого в том, что он теряет поток пользовательского интерфейса, создавший это представление, при перезапуске активности.

Как вы можете видеть, есть две строки, прокомментированные при перезагрузке симулятора, где я также безуспешно пытался сохранить объект NavigationDrawer в тесте: такое же поведение.

Я также попытался сохранить prevActivity и в методе showHUD(), сначала спросив, является ли он нулевым, а если нет, выполнить метод внутри prevActivity. Ожидая, что он получит доступ к исходному потоку пользовательского интерфейса, но я ошибся.

Есть ли решение сохранить этот поток пользовательского интерфейса во время перезапуска активности? или, может быть, другой тип решения?

Большое спасибо.


person XaviGG    schedule 07.05.2014    source источник


Ответы (3)


Вы должны проверить свой onSavedInstanceState в своей деятельности. Вот как ОС Android предназначена для решения этой проблемы. Вы пытаетесь сделать это самостоятельно, когда вам следует полагаться на функциональность, предоставляемую ОС.

Довольно много примеров этого (если вы ищете SO):

Android: эффективное управление поворотом экрана

Обработка поворота экрана без потери данных — Android

person Booger    schedule 07.05.2014
comment
Я перешел на официальное решение (сохранение фрагмента). Он работает точно так же, как и раньше: данные сохраняются, но метод, выполняемый в потоке пользовательского интерфейса, ничего не делает. - person XaviGG; 09.05.2014

Если вы хотите сохранить конфигурацию, вам нужно сохранить определенные вещи. Вы можете сделать это в onPause() или onSaveInstanceState().

Если onCreate() вызывается после изменения конфигурации, вы можете получить то, что вам нужно, из пакета. когда вы получите его обратно, вы можете установить то, что вам нужно.

См. это: http://developer.android.com/training/basics/activity-lifecycle/recreating.html

person user2696372    schedule 07.05.2014
comment
Пакет - не лучшее решение для больших объектов данных. Альтернативой является сохранение фрагмента, но я получаю такое же поведение. - person XaviGG; 09.05.2014
comment
Согласованный. Это зависит от того, сколько данных вы хотите хранить. - person user2696372; 09.05.2014

Я правильно сохраняю объект данных, но после поворота устройства функция в потоке пользовательского интерфейса не действует, функция для изменения выбранного раздела в NavigationDrawer. Я думал, что это из-за того, что я терял правильный поток пользовательского интерфейса, но на самом деле я терял этот NavigationDrawerFragment.

Простое добавление строки setRetainInstance(true) в OnCreate() NavigationDrawerFragment решает проблему:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
    ...
person XaviGG    schedule 09.05.2014