web-dev-qa-db-ja.com

Activity.finish()メソッドは何をしているのですか?

私はしばらくの間Androidアプリケーションを開発していて、活動のライフサイクルとアプリケーションのライフサイクルについて多くの記事を続けてきました。

私はActivity.finish()メソッドがActivity.onDestroy()へのやり方でどこかで呼び出し、そしてまた活動をスタックから取り除くことを知っています、そしてそれがどういうわけか彼が "彼のトリックをする"そうやって時間....

私はこの記事に来ました--- アプリケーションを終了するのが面倒ですか? そしてMark Murphyの答えを読んでください。

finish()メソッドが実際に何をするのかについて少し混乱しました。

finish()を呼び出してonDestroy()が呼び出されない可能性はありますか?

143
Tal Kanel

アクティビティに対してfinish()を呼び出すと、メソッドonDestroy()が実行されます。このメソッドは以下のようなことができます。

  1. アクティビティが管理していたダイアログをすべて閉じます。
  2. アクティビティが管理していたカーソルをすべて閉じます。
  3. 開いている検索ダイアログを閉じます

また、onDestroy()はデストラクタではありません。それは実際にはオブジェクトを破壊しません。それは特定の状態に基づいて呼び出されるメソッドです。したがって、スーパークラスのonDestroy()が実行されて戻った後も、インスタンスはまだ生きていて非常によく動作しています。プロセスは何もしないでしょう、そしてメモリが回収される必要があるならプロセスは殺されます

153
K_Anas

@ K_Anasに対する私の2セントが答えます。私はfinish()メソッドで簡単なテストを行いました。アクティビティのライフサイクルにおける重要なコールバックメソッドのリスト

  1. OnCreate()でfinish()を呼び出す:onCreate() - > onDestroy()
  2. OnStart()でfinish()を呼び出す:onCreate() - > onStart() - > onStop() - > onDestroy()
  3. OnResume()でfinish()を呼び出す:onCreate() - > onStart() - > onResume() - > onPause() - > onStop() - > onDestroy()

私が言おうとしているのは、finish()が実行されると、そのメソッドの対応するものとその間にあるメソッドが呼び出されるということです。

例えば:

 onCreate() counter part is onDestroy()
 onStart() counter part is onStop()
 onPause() counter part is onResume()
66
Prakash

また、意図した後にfinish()を呼び出した場合、「戻る」ボタンで前のアクティビティに戻ることはできません。

startActivity(intent);
finish();
21
Dan Wears Prada

onDestroy()は最終的なクリーンアップのためのものです - あなたが自分でできるリソースを解放し、開いた接続、読者、作家などを閉じます。あなたがそれを上書きしないなら、システムはそれがしなければならないことをする。

一方、finish()は、プログラマーが現在のActivityを終了させたいことをシステムに知らせるだけです。そしてそれゆえに、その後onDestroy()を呼び出します。

注意すべきこと

のみfinish()への呼び出しがonDestroy()への呼び出しをトリガーする必要はありません。いいえ。Androidシステムでは、現在のActivityに必要なリソースが解放される必要があると感じた場合は、活動を自由に停止できます。

12
Kazekage Gaara

Finish()メソッドは現在のアクティビティを破壊します。ユーザーが戻るボタンを押したときにこのアクティビティを何度もロードしたくない場合に、このメソッドを使用できます。基本的には現在のスタックからアクティビティをクリアします。

6
Udit Kapahi

Finish()はonPause()とonStop()をスキップして直接onDestroy()を実行することができると様々な答えと注意が主張しています。公平を期すために、これに関するAndroidのドキュメント( http://developer.Android.com/reference/Android/app/Activity.html )には、「アクティビティは終了しているか、システムによって破棄されています」と記載されています。あいまいですが、finish()がonDestroy()にジャンプする可能性があります。

Finish()のJavaDocも同様に期待外れであり( http://developer.Android.com/reference/Android/app/Activity.html#finish() )、実際にはどのようなメソッドに言及していません。 )はfinish()に応答して呼び出されます。

だから私はエントリの各状態を記録する以下のこのミニアプリを書きました。それはfinish()を呼び出すボタンを含んでいます - それであなたはどのメソッドが起動したかのログを見ることができます。この実験はfinish()が実際にもonPause()とonStop()を呼び出すことを示唆しています。これが私が得る出力です:

2170-2170/? D/LIFECYCLE_DEMO﹕ INSIDE: onCreate
2170-2170/? D/LIFECYCLE_DEMO﹕ INSIDE: onStart
2170-2170/? D/LIFECYCLE_DEMO﹕ INSIDE: onResume
2170-2170/? D/LIFECYCLE_DEMO﹕ User just clicked button to initiate finish() 
2170-2170/? D/LIFECYCLE_DEMO﹕ INSIDE: onPause
2170-2170/? D/LIFECYCLE_DEMO﹕ INSIDE: onStop 
2170-2170/? D/LIFECYCLE_DEMO﹕ INSIDE: onDestroy

package com.mvvg.apps.lifecycle;

import Android.app.Activity;
import Android.os.Bundle;
import Android.util.Log;
import Android.view.View;
import Android.view.View.OnClickListener;
import Android.widget.Button;
import Android.widget.LinearLayout;
import Android.widget.Toast;

public class AndroidLifecycle extends Activity {

    private static final String TAG = "LIFECYCLE_DEMO";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "INSIDE: onCreate");
        setContentView(R.layout.activity_main);
        LinearLayout layout = (LinearLayout) findViewById(R.id.myId);
        Button button = new Button(this);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View view) {
                Toast.makeText(AndroidLifecycle.this, "Initiating finish()",
                        Toast.LENGTH_SHORT).show();
                Log.d(TAG, "User just clicked button to initiate finish()");
                finish();
            }

        });

        layout.addView(button);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "INSIDE: onStart");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "INSIDE: onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "INSIDE: onDestroy");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "INSIDE: onPause");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "INSIDE: onResume");
    }

}
4
CoderOfTheNight

@ user3282164 Activity ライフサイクルによると、onPause()を呼び出すと、onStop() - > onDestroy() - > finish()の順に進みます。

この図は、システムに起因する[Activity Running]から[onDestroy()]への直線的なパスを示していません。

onStop() docは "と言うことに注意してください。システムに保持するのに十分なメモリがない場合、このメソッドはneverと呼ばれることがあります。 onPause()メソッドが呼び出された後にアクティビティのプロセスが実行されます。 "

3
Marie

上記の@rommex回答に加えて、私はfinish()がActivityの破棄を待ち行列に入れ、それがActivityの優先順位に依存することにも気付きました。

finish()の後にonPause()を呼び出すと、onStop()が表示され、onDestroy()がすぐに呼び出されます。

finish()の後にonStop()を呼び出した場合、5分後までonDestroy()は表示されません。

私の観察によると、仕上げは待ち行列に入っていて、adb Shell dumpsys activity activitiesを見たときはfinishing=trueに設定されていましたが、最前面にはないため、破棄の優先順位は付けられませんでした。

要約すると、onDestroy()が呼び出されることは保証されていませんが、呼び出された場合でも遅延する可能性があります。

2
Brandon Lim

私の調査によると、finish()メソッドは実際にはいくつかの破壊操作をキューに入れますが、Activityはすぐには破壊されません。破壊は予定されています。

たとえば、finish()をまだ実行していないときにonActivityResult()コールバックにonResume()を配置すると、最初にonResume()が実行され、その後でのみonStop()onDestroy()が呼び出されます。

注:onDestroy()は、 ドキュメント に記載されているように、まったく呼び出すことはできません。

2
rommex

onCreate()でfinishを呼び出しても、@ prakashが言ったように直接onDestroy()を呼び出すことはありません。 finish()操作は、Androidに制御が戻るまで開始されません。

onCreate()でfinish()を呼び出す:onCreate() - > onStart() - > onResume()ユーザーがアプリを終了すると - > onPause() - > onStop() - > onDestroy()が呼び出されます

onStart()でfinish()を呼び出す:onCreate() - > onStart() - > onStop() - > onDestroy()

onResume()でfinish()を呼び出す:onCreate() - > onStart() - > onResume() - > onPause() - > onStop() - > onDestroy()

さらなる参照チェックのためにこれを見てください 終了後に継続的に作成するfinish()について

1
anand krish

これまでのところ、ここでの唯一の正しい答えはromnexによって与えられたようです: "onDestroy()はまったく呼ばれないかもしれません"。実際には、ほとんどすべての場合に保証されるわけではありません。 documentation on finish()は、アクティビティの結果が呼び出し元に伝搬されることを約束するだけですが、それ以上はありません。さらに ライフサイクルドキュメンテーション はonStop()が終了するとすぐに(あるいはより古いデバイスではそれよりも早く)アクティビティがOSによって強制終了されることを明確にしています。テスト、onDestroy()が実行されている間、または実行される前にアクティビティが強制終了される可能性があることを意味します。

そのため、finish()を呼び出したときに何らかの処理が行われたことを確認したい場合は、onDestroy()に入れることはできませんが、実際に呼び出す直前に、finish()を呼び出した場所と同じ場所で行う必要があります。

0
urps