StartActivityForResult не работает должным образом с помощью launchMode singleInstance

Мне бы хотелось, чтобы в моем приложении Activity Activity был задействован только один экземпляр. У меня есть несколько экранов, которые являются ListActivities, и я бы не стал испытывать боль и страдания обновления списков в предыдущем экземпляре ListActivity, когда другой экземпляр этого ListActivity был изменен (добавлен, отредактирован, удален и т.д.), (или есть простой способ сделать это?).

Примечание. Я прочитал, что singleTop выполнит это (хотя он уничтожает действие, если вы нажмете кнопку "Назад" ), но он не работает. У меня есть меню, и если я перейду на мой экран "Входящие" , я перейду на экран QuickList, а затем снова перейду на мой экран "Входящие" , он создаст новую активность "Входящие" .

Прямо сейчас, в моем ListActivities, у меня установлен режим запуска для singleInstance. Проблема в том, что если я запускаю другое действие с использованием startActivityForResult, обработчик onActivityResult запускается сразу (до создания нового действия). Когда я выполняю необходимое действие на следующем экране, чтобы вернуть результат, обработчик onActivityResult не запускается.

Что происходит?

Вот как я запускаю новую активность:

Intent intentLaunchQuickList = new Intent(ActivityMyList.this, ActivityQuickList.class);
startActivityForResult(intentLaunchQuickList, REQUEST_QUICKLIST);

Вот как я возвращаю результат:

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    QuickListItem qlItem = m_Adapter.getItem(position);
    if (qlItem != null && qlItem.getQLId() != -1) {
        Intent data = new Intent();
        data.putExtra("ql_id", qlItem.getQLId());
        if (getParent() == null) {
            setResult(Activity.RESULT_OK, data);
        }
        else {
            getParent().setResult(Activity.RESULT_OK, data);
        }
    }
    finish();
}

Вот мой обработчик onActivityResult:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_QUICKLIST) {
        if (resultCode == Activity.RESULT_OK) {
            Bundle extras = data.getExtras();
            if (extras != null) {
                int id = extras.getInt("ql_id");
                if (id > 0) {
                    launchQLItemsThread(id);
                }
            }
        }
    }
}

Ответы

Ответ 1

Из документации startActivityForResult: "Например, если действие, которое вы запускаете, использует режим запуска singleTask, оно не будет выполняться в вашей задаче и, следовательно, вы сразу получите результат отмены". Действия singleInstance одинаковы.

Другими словами, если вы хотите использовать sAFR, вам нужно будет обрабатывать несколько экземпляров активности. Я бы посоветовал сохранить состояние списка для ваших экземпляров ListActivity в onPause для какого-либо глобального приложения (одноэлементного или любого другого) и загрузить оттуда в onResume. Затем, даже если будут созданы несколько экземпляров ListActivity, верхний будет всегда обновлять данные до того, как старые будут возобновлены, а списки всегда будут отображаться для пользователя.

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

Ответ 2

У меня есть несколько экранов, которые ListActivities, и я бы не хотел через боль и страдания обновление списков в предыдущем экземпляр ListActivity, когда другой экземпляр этого ListActivity (или есть простой способ сделайте это?).

Используйте согласованную модель. Например, ваши данные, можно надеяться, находятся в базе данных. Каждый ListActivity имеет Cursor для части необходимой ему базы данных. Пусть Cursor будет "управляемым курсором" (через startManagingCursor()), а ваш ListViews автоматически обновится в onResume(). Затем вы делаете свои изменения в своей модели через базу данных.

У меня есть меню, и если я перейду в папку "Входящие" экран, затем я иду в свой QuickList экран, а затем я перейду в папку "Входящие" экран снова, он создает новую папку "Входящие" Активность.

То, что он должен делать. Цитирование документация:

"Стандартный" и "SingleTop" режимы отличаются друг от друга только одним уважение: каждый раз, когда появляются новые намерения для "стандартной" деятельности новый экземпляр класса создается для ответьте на это намерение. Каждый экземпляр обрабатывает одно намерение. Аналогичным образом, новый экземпляр действия "singleTop" также могут быть созданы для обработки нового намерение. Однако, если целевая задача уже имеет существующий экземпляр деятельность в верхней части ее стека, этот экземпляр получит новый намерение (в вызове onNewIntent()); новый экземпляр не создается. В другие обстоятельства - например, если существующий экземпляр Активность "singleTop" находится в целевой но не в верхней части стека, или если он находится в верхней части стека, но а не в целевой задаче - новый экземпляр будет создан и нажат в стеке.

(выделение жирным шрифтом для акцента)

Прямо сейчас, в моем ListActivities, у меня установлен режим запуска для singleInstance.

Пожалуйста, не делайте этого.