2010-04-20 29 views
90

Próbuję ustawićRozmiar po naciśnięciu przycisku BACK. Zadzwonię w onDestroyFunkcja setResult nie działa po naciśnięciu przycisku BACK

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

Ale jeśli chodzi o

onActivityResult(int requestCode, int resultCode, Intent data) 

ResultCode wynosi 0 (RESULT_CANCELED) oraz dane jest 'zerowy'.

Jak mogę przekazać wynik z działania zakończonego przyciskiem POWRÓT?

Odpowiedz

9

I refactored my code. Początkowo przygotowałem dane i ustawiłem je jako activity result w onDestroy (to nie zadziałało). Teraz ustawiam activity danych za każdym razem, gdy dane do zwrócenia są aktualizowane i nie mają nic w onDestroy.

+0

To nie działa dla mnie, ponieważ moje dane są update w "onPause" – Bostone

+0

Jeśli twoja aktywność zostanie odtworzona po wywołaniu 'setResult()', twoje dane zostaną utracone. –

0

onDestroy jest zbyt późno w łańcuchu — zamiast zastąpić i sprawdzić isFinishing() aby sprawdzić, czy działalność jest na końcu cyklu ich życia.

+1

Nie, to też jest za późno. – alex2k8

+1

Och, whoops .. :) –

+0

Właściwie nazywam to błędem: http://code.google.com/p/android/issues/detail?id=1671. W złożonych aplikacjach myślę, że z tego powodu jest tylko pewne zachowanie, którego nie można zaprogramować. – pjv

56

Activity wynik musi być ustawiony przedfinish() jest wywoływana. Kliknięcie BACK faktycznie nazywa finish() na swojej activity, więc można użyć następującego fragmentu:

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

    super.finish(); 
} 

Jeśli zadzwonisz NavUtils.navigateUpFromSameTask(); w onOptionsItemSelected(), finish() nazywa, ale dostaniesz złą result code. Musisz więc zadzwonić pod numer finish(), a nie navigateUpFromSameTask w onOptionsItemSelected(). wrong requestCode in onActivityResult

+0

Działa to w przypadku OP, ale ogólnie nie, prawda? Istnieje więcej metod niż finish(), które powodują koniec cyklu życia aplikacji (za pomocą onPause() i onDestroy())? Zobacz także mój komentarz w innej odpowiedzi. – pjv

+0

A nawet gdyby tak nie było, nie wiedziałbyś o tym, kiedy zostanie wprowadzony w aktualizacji API. Nie tak łatwo jak wtedy, gdy zmieni się zachowanie onPause() lub onDestroy(). Są to metody, które * masz * zastąpić. – pjv

+5

@pjv - Nie rozumiem, co 'finish' ma wspólnego z' onPause' i 'onDestroy'? Nie są one całkowicie powiązane, z wyjątkiem tego, że 'finish' rozpoczyna proces kończenia, którego częścią są' onPause' i 'onDestroy'. – JBM

3

Patrz onActivityResult(int, int, Intent) doc

Rozwiązanie jest sprawdzenie ResultCode na wartość Activity.RESULT_CENCELED. Jeśli tak, oznacza to, że naciśnięto przycisk WSTECZ lub wystąpił błąd. Mam nadzieję, że to działa dla was, pracuje dla mnie :).

+0

To jest dokładne rozwiązanie .. Musisz Wynik kodu. Nikt nie może ustawić wyniku innego niż w kodzie. Tak więc, jeśli wynik nie jest w porządku, oznacza to, że albo jego back prasy, albo Crashhed .. – John

0

Spróbuj nadrzędnymi onBackPressed (od android poziom 5 w górę) lub zastąpić onKeyDown() i złapać KeyEvent.BUTTON_BACK (patrz Android Activity Results) To załatwia sprawę dla mnie.

128

Trzeba overide metodę onBackPressed() i ustawić wynik przed wywołaniem nadrzędnej, czyli

@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

Należy zauważyć, że jeśli używasz tego podejścia, wywołanie super.onBackPressed() musi nastąpić po wywołaniu setResult(), jak pokazano powyżej lub będziesz miał oryginalny problem od nowa! – jengelsma

+1

To najlepsza odpowiedź tutaj. Jeśli przesłonimy on onPause() lub onDestroy(), onBackPressed() zostanie wywołany jako pierwszy i ustawi wynik na 0. Pamiętaj, że! – Marek

+0

lub możesz ustawić domyślny wynik onCreate. Każde miejsce przed metą() jest w porządku. –

0

nie należy liczyć na jakiekolwiek logiki zawartej w OnPause jednej działalności po powrocie do początkowego jeden. Zgodnie z docs:

implementacji tej metody (OnPause) musi być bardzo szybki, ponieważ następna czynność nie zostanie wznowione, dopóki ta metoda zwraca

Zobacz http://goo.gl/8S2Y szczegóły.

Najbezpieczniejszym sposobem jest ustawiony wynik po każdej operacji wynik przerabianie jest kompletna (jak wspomina w swojej odpowiedzi)

2

powinny przesłonić onOptionsItemSelected takiego:

@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

i wklej odpowiedź może być pomocne dla innych osób: , gdy zestaw launcheMode z Androidem: launchMode = "singleTask" również nie mogę uzyskać wyniku,

 /* <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. 
*/ 

oraz:

 /* <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

Jeśli chcesz ustawić jakiś zwyczaj RESULT_CODE w onBackPressed razie to trzeba najpierw ustawić result a następnie wywołać super.onBackPressed() a otrzymasz ten sam RESULT_CODE w działalność rozmówcy onActivityResult metoda

@Override 
    public void onBackPressed() 
    { 
     setResult(SOME_INTEGER); 
     super.onBackPressed(); 
    } 
Powiązane problemy