戻るボタンを押したときにsetResultが機能しない


111

戻るボタンを押した後、setResultを実行しようとしています。onDestroyを呼び出す

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

しかし、それに関しては

onActivityResult(int requestCode, int resultCode, Intent data) 

resultCodeは0(RESULT_CANCELED)で、データは「null」です。

では、[戻る]ボタンで終了したアクティビティの結果をどのように渡すことができますか?

回答:


159

スーパークラスを呼び出す前に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();
}

23
このアプローチを使用する場合、上記のようにsetResult()を呼び出した後にsuper.onBackPressed()を呼び出す必要があります。そうしないと、元の問題が再び発生します。
jengelsma

1
これが最良の答えです。onPause()またはonDestroy()をオーバーライドすると、最初にonBackPressed()が呼び出され、結果が0に設定されます。
Marek 2013

または、onCreateでデフォルトの結果を設定できます。finish()の前のどの場所でも問題ありません。
Helin Wang 2013

5
私は同様のアプローチを実装しましたが、それでも機能しません。たとえば私は、要求コードと意図作業を持っていますが、resultCodeが、常に0です。
ネオンWarge

68

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()onActivityResultの間違ったrequestCode


これはOPのケースでは機能しますが、一般的には機能しません。アプリのライフサイクルの終了を誘発するfinish()よりも多くのメソッドがあります(onPause()およびonDestroy()を使用)?他の回答でも私のコメントを参照してください。
pjv 2011年

そして、それがなかったとしても、APIの更新でいつ導入されるかはわかりません。onPause()またはonDestroy()の動作が変更されたときほど簡単ではありません。これらは、オーバーライドすることになっているメソッドです。
pjv 2011年

6
@pjv-私はあなたの要点を理解しfinishていません、onPauseそして何と関係がありonDestroyますか?それらはfinish、終了プロセスを開始することを除いて、まったく関係ありません。onPauseonDestroyの一部であるが。
JBM 2011

20

あなたはいくつかのカスタムを設定したい場合RESULT_CODEonBackPressed、イベントを最初に設定する必要がありresult、その後、呼び出すsuper.onBackPressed()とあなたが同じを受け取るRESULT_CODE呼び出し側の活動の中でonActivityResultの方法

    @Override
    public void onBackPressed()
    {
         setResult(SOME_INTEGER);
         super.onBackPressed();
    }

10

コードをリファクタリングしました。最初にいくつかのデータを準備し、次のように設定しましactivity resultonDestroy(これは機能しませんでした)。これでactivity、返されるデータが更新されるたびにデータを設定し、には何もありませんonDestroy


私のデータは "onPause"で更新されているため、これは私には機能しません
Bostone

を呼び出した後にアクティビティが再作成setResult()されると、データは失われます。
ジャレットミラード

3

次のように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);
    }
}

2

参照 onActivityResult(int、int、Intent)ドキュメントを

解決策は、値Activity.RESULT_CENCELEDresultCodeを確認することです。はいの場合は、戻るが押されたか、アクティビティがクラッシュしたことを意味します。それがあなたたちのために働くことを願って、私のために働く:)。


これが正確な解決策です。結果コードを作成する必要があります。コード以外では、誰も結果を設定できません。だから、結果がでない場合はOK手段のいずれかにその背中を押すまたはクラッシュ...
ジョン

0

onDestroyチェーンの中で手遅れです—代わりにオーバーライドonPauseしてチェックisFinishing()し、アクティビティがライフサイクルの最後にあるかどうかを確認してください。


1
いいえ、これも遅すぎます。
alex2k8 2010

これを実際にバグと呼びます:code.google.com/p/android/issues/detail?id=1671。複雑なアプリケーションでは、これが原因でプログラムできない動作がいくつかあると思います。
pjv 2011年

また、非常に直観に反しています。私が同じ過ちを犯し続けているほど、今では2年間以上です。
pjv 2011年

実際には-これはさらに悪いです。そして、私がコーディングしているように、それはJBに存在します。onPauseからsetResultを呼び出すと実行されますが、onActivityReturnの実行時にresultCodeもdataも設定されません。どうして?
Bostone 2012

そして、それが理由です。「このメソッドが返されるまで次のアクティビティは再開されないため、このメソッドの実装(onPause)は非常に迅速でなければなりません。」goo.gl/8S2Y
Bostone

0

onBackPressed(Androidレベル5以降)をオーバーライドするか、onKeyDown()をオーバーライドしてKeyEvent.BUTTON_BACKをキャッチします(Androidアクティビティの結果を参照)これは私にとってはトリックです。


0

最初のアクティビティに戻るときに、1つのアクティビティのonPauseで実行されるロジックに依存しないでください。ドキュメントによると:

このメソッド(onPause)の実装は、このメソッドが戻るまで次のアクティビティが再開されないため、非常に高速でなければなりません。

詳細については、http://goo.gl/8S2Yをご覧ください。

最も安全な方法は、結果を変更する各操作が完了した後に結果を設定することです(回答で述べたように)


0

答えを貼り付けると、他の人の役に立つかもしれません:android:launchMode = "singleTask"で設定されたlauncheModeでも結果を取得できない場合、ドキュメントには次のように記載されています。

     /* <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. 
 */
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.