2013-05-30 1 views
1

У меня есть два вида деятельности: PictureList и AddPictures. От деятельности PictureList я запрашивающая деятельность результата, как это:onActivityResult не получил правильного результата после возвращения, потому что активизированная его деятельность была воссоздана?

Intent myIntent = new Intent(PictureList.this, AddPictures.class); 
Bundle b = new Bundle(); 
b.putInt("iEntry", clickCounter); 
b.putBoolean("bAddPicture", true); 
b.putBoolean("bEditPicture", false); 
myIntent.putExtras(b); 
startActivityForResult(myIntent,1); 

Я также реализующего соответствующие onActivityResult здесь:

protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (requestCode == 1) { 
     if(resultCode == RESULT_OK){   
      iReturnedEntry = data.getIntExtra("iReturnedEntry", 0); 
     } 
     if (resultCode == RESULT_CANCELED) {  
     } 
     } 
    } 
} 

С другой деятельностью, AddPictures, принимают параметры:

Bundle b = getIntent().getExtras(); 
iEntry = b.getInt("iEntry"); 
bAddPicture = b.getBoolean("bAddPicture", false); 
bEditPicture = b.getBoolean("bEditPicture", false); 

и когда он должен вернуться он делает это так:

Intent returnIntent = new Intent(); 
returnIntent.putExtra("iReturnedEntry", iEntry); 
setResult(RESULT_OK,returnIntent);  

Обычно приложение работает нормально, но очень часто бывает, что результат не сохраняется. Я думаю, что из-за какого-либо управления памятью или по другой причине активность PictureList воссоздается или снова вызывает метод onCreate после возвращения из активности AddPictures, и из-за этого onActivityResult не работает. Как я могу решить эту проблему?

ответ

1

Если вы ждете результата от другой деятельности, лучше всего, чтобы сохранить параметры как общие предпочтения, а затем загрузить их обратно в предыдущей деятельности во onResume. Таким образом, данные не будут потеряны из-за воссоздания активности, которая содержит onActivityResult.

Тогда для первой активности PictureList, код изменился в этом:

bPictureRequested = true; 
bPictureReceived = false; 
appSharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE); 
preferencesEditor = appSharedPreferences.edit(); 
preferencesEditor.putBoolean("bPictureReceived", bPictureReceived); 
preferencesEditor.commit(); 

Intent myIntent = new Intent(PictureList.this, AddPictures.class); 
Bundle b = new Bundle(); 
b.putInt("iEntry", clickCounter); 
b.putBoolean("bAddPicture", true); 
b.putBoolean("bEditPicture", false); 
myIntent.putExtras(b); 
startActivity(myIntent); 

и в onResume я добавил следующие строки для того, чтобы получить результат:

if(bPictureRequested){ 
     appSharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE); 
     bPictureReceived = appSharedPreferences.getBoolean("bPictureReceived", false); 
     if(bPictureReceived){ 
       iReturnedEntry = appSharedPreferences.getInt("iReturnedEntry", 0); 
       // Reset the flags 
       bPictureRequested = false; 
       bPictureReceived = false; 
       preferencesEditor = appSharedPreferences.edit(); 
       preferencesEditor.putBoolean("bPictureReceived", bPictureReceived); 
       preferencesEditor.commit(); 
     } 
} 

Теперь, в другой активности AddPictures я оставил ту же самую часть, которая получает предыдущие параметры по значению, но изменила способ возврата данных с использованием общих настроек:

appSharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE); 
preferencesEditor = appSharedPreferences.edit(); 
preferencesEditor.putBoolean("bPictureReceived", true); 
preferencesEditor.putInt("iReturnedEntry", iEntry); 
preferencesEditor.commit(); 
finish(); 

Теперь все работает нормально.

0

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

Ознакомьтесь с жизненным циклом деятельности here и используйте методы onPause() и onResume(), чтобы сохранить и восстановить состояние активности PictureList, поскольку действие приостановлено и возобновлено.

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

+0

Спасибо Фил. Я понимаю, что действия создаются и уничтожаются часто и что это нужно обрабатывать с помощью onPause и onResume, но что происходит, когда вы вызываете startActivityForResult из одного действия, а позже это действие воссоздается, когда вы возвращаетесь с результатом? Как работает onActivityResult в этом случае? –

+0

Я обнаружил трудный способ, с помощью которого onActivityResult() вызывается до onCreate() в ситуации воссоздания вызывающей активности. Таким образом, самый безопасный подход - просто сохранить ответ на переменную экземпляра в onActivityResult(), а затем действовать на нее в onResume(). Поскольку onResume() вызывается даже тогда, когда onCreate() не выполняет эту функцию для обоих сценариев без какой-либо условной логики. Конечно, вам нужно очистить переменную экземпляра как последнюю часть onResume(), чтобы в следующий раз через нее снова не использовать. – Phil

+0

Я последовал твоему предложению, но это не сработало. in onActivityResult Я сохранил ответ, а также активировал логический флаг, который позже я проверил в onResume. Впоследствии, когда флаг отмечен как true, я загрузил возвращаемые значения, но все же они были пустыми. –

0

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

для класса AddPictures, попробуйте сохранить данные из метода onSaveInstanceState (Bundle outState) из Activity и получить их в методе onCreate(). Метод Theses восстанавливает ваши данные, если ваша активность воссоздана.

Пример:

@Override 
    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putString("iReturnedEntry", iEntry); 
    } 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     if (savedInstanceState != null) { 
      String dataSaved = savedInstanceState.getString("iReturnedEntry"); 
      Log.v("HelloWorldActivity", "iReturnedEntry=" + dataSaved); 
     } 

    } 
+0

Спасибо, Jarvis. На самом деле я реализую этот метод и для других целей, но моя проблема в том, что я ожидаю результат от другого действия, используя startActivityForResult, и кажется, что при первом воссоздании первого действия функциональность onActivityResult влияет как-то. –

Смежные вопросы