2010-04-20 4 views
90

Я пытаюсь установитьResult после нажатия кнопки BACK. Я призываю в OnDestroysetResult не работает, когда нажата кнопка BACK

Intent data = new Intent(); 
setResult(RESULT_OK, data) 

Но когда дело доходит до

onActivityResult(int requestCode, int resultCode, Intent data) 

ResultCode является 0 (RESULT_CANCELED) и данные 'нулевой'.

Итак, как я могу передать результат деятельности, завершенной кнопкой BACK?

ответ

9

Я реорганизовал свой код. Сначала я подготовил некоторые данные и установил их как activity result в onDestroy (это не сработало). Теперь я устанавливаю activity данные каждый раз, когда данные, которые будут возвращены, обновляются и ничего не имеют в onDestroy.

+0

Это не работает для меня, так как мои данные обновление в «onPause» – Bostone

+0

Если ваша деятельность воссоздается после вызова 'setResult()', ваши данные будут потеряны. –

0

onDestroy слишком поздно в цепи — вместо переопределения и проверить isFinishing(), чтобы проверить, если ваша деятельность в конце своего жизненного цикла.

+1

Нет, это уже слишком поздно. – alex2k8

+1

О, крики .. :) –

+0

Я на самом деле называю это ошибкой: http://code.google.com/p/android/issues/detail?id=1671. В сложных приложениях, я думаю, из-за этого есть только какое-то поведение, которое вы не можете запрограммировать. – pjv

56

Activity результат должен быть установлен доfinish() называется. Нажатие кнопки Назад фактически вызывает finish() на вашем activity, так что вы можете использовать следующий фрагмент кода:

@Override 
public void finish() { 
    Intent data = new Intent(); 
    setResult(RESULT_OK, data); 

    super.finish(); 
} 

Если вы звоните NavUtils.navigateUpFromSameTask(); в onOptionsItemSelected(), finish() называется, но вы получите неправильный result code. Поэтому вы должны позвонить finish() не navigateUpFromSameTask в onOptionsItemSelected(). wrong requestCode in onActivityResult

+0

Это работает в случае OPs, но не в целом, правильно? Есть больше методов, чем finish(), которые вызывают конец жизненного цикла приложения (через onPause() и onDestroy())? Также см. Мой комментарий в другом ответе. – pjv

+0

И даже если бы этого не было, вы не узнаете об этом, когда оно будет введено в обновлении API. Не так легко, как если бы вы изменили поведение onPause() или onDestroy(). Это методы, которые вы * предположили * переопределить. – pjv

+5

@pjv - Я не понимаю, что значит «закончить» с 'onPause' и' onDestroy'? Все это совершенно не связано, за исключением того, что 'finish' запускает процесс завершения, частью которого являются' onPause' и 'onDestroy'. – JBM

3

См onActivityResult(int, int, Intent) doc

Решение, чтобы проверить ResultCode для значения Activity.RESULT_CENCELED. Если да, то это означает, что нажата кнопка BACK или произошел сбой активности. Надеюсь, он работает для вас, ребята, работает для меня :).

+0

Это точное решение .. Вы должны получить код. Никто не может установить результат, отличный от вас в коде. Итак, если результат не является ОК, значит, его обратные нажатия или сбой .. – John

0

Попробуйте перекрывая onBackPressed (от андроида уровня 5), или переопределить OnKeyDown() и поймать KeyEvent.BUTTON_BACK (см Android Activity Results) Это делает трюк для меня.

128

Вам нужно overide метод onBackPressed() и установить результат до вызова суперкласса, т.е.

@Override 
public void onBackPressed() { 
    Bundle bundle = new Bundle(); 
    bundle.putString(FIELD_A, mA.getText().toString()); 

    Intent mIntent = new Intent(); 
    mIntent.putExtras(bundle); 
    setResult(RESULT_OK, mIntent); 
    super.onBackPressed(); 
} 
+16

Обратите внимание, что если вы используете этот подход, вызов super.onBackPressed() должен произойти после вызова setResult(), как показано выше, или у вас будет оригинал проблема сначала! – jengelsma

+1

Это лучший ответ здесь. Если мы переопределим onPause() или onDestroy(), onBackPressed() будет вызван первым, и он установит результат на 0. Пожалуйста, помните об этом! – Marek

+0

или вы можете установить результат по умолчанию в onCreate. Любое место перед финишем() отлично. –

0

Не следует полагаться на какой-либо логики, выполненной в OnPause одной деятельности, когда вы вернетесь в исходное один. Согласно документации:

Реализации этого метода (OnPause) должны быть очень быстро, потому что следующая деятельность не будет возобновлена, пока этот метод не возвращает

См http://goo.gl/8S2Y подробности.

Самый безопасный способ установить результат после каждой операции результат изменяющий завершения (как вы упоминаете в своем ответе)

2

Вы должны переопределить onOptionsItemSelected так:

@Override 
public boolean onOptionsItemSelected(final MenuItem item) { 
    switch (item.getItemId()) { 
    case android.R.id.home: 
     final Intent mIntent = new Intent(); 
     mIntent.putExtra("param", "value"); 
     setResult(RESULT_OK, mIntent); 
     finish(); 
     return true; 
    default: 
     return super.onOptionsItemSelected(item); 
    } 
} 
0

я вставить ответ может быть полезным для других людей: , когда набор запускается с помощью android: launchMode = "singleTask" Я также не могу получить результат, в документе говорится:

 /* <p>Note that this method should only be used with Intent protocols 
* that are defined to return a result. In other protocols (such as 
* {@link Intent#ACTION_MAIN} or {@link Intent#ACTION_VIEW}), you may 
* not get the result when you expect. For example, if the activity you 
* are launching uses the singleTask launch mode, it will not run in your 
* task and thus you will immediately receive a cancel result. 
*/ 

и:

 /* <p>As a special case, if you call startActivityForResult() with a requestCode 
* >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your 
* activity, then your window will not be displayed until a result is 
* returned back from the started activity. This is to avoid visible 
* flickering when redirecting to another activity. 
*/ 
13

Если вы хотите установить некоторые пользовательские RESULT_CODE в onBackPressed случае, то вам необходимо сначала установить result, а затем вызвать super.onBackPressed(), и вы получите тот же RESULT_CODE в деятельности вызывающего абонента onActivityResult метод

@Override 
    public void onBackPressed() 
    { 
     setResult(SOME_INTEGER); 
     super.onBackPressed(); 
    } 
Смежные вопросы