关于android:Activity.finish()方法到底在做什么?

what exactly Activity.finish() method is doing?

我正在开发Android应用程序一段时间,并且关注了很多关于活动生命周期和应用程序生命周期的帖子。

我知道Activity.finish()方法调用Activity.onDestroy()的方式,并从堆栈中删除活动,我想它以某种方式指向操作系统和垃圾收集器,他可以"做他的伎俩"并释放内存时 找到这样的好时机....

我来到这个帖子 -
退出申请不赞成? 并阅读Mark Murphy的回答。

它让我对finish()方法究竟是做什么感到困惑。

我有可能打电话给finish()并且不会打电话给onDestroy()吗?


在活动上调用finish()时,将执行方法onDestroy()。这种方法可以做到这样的事情:

  • 关闭活动正在管理的任何对话框。
  • 关闭活动管理的所有游标。
  • 关闭所有打开的搜索对话框
  • 此外,onDestroy()不是析构函数。它实际上并没有破坏对象。它只是一种基于某种状态调用的方法。因此,在超类的onDestroy()运行并返回之后,您的实例仍然存活且非常好* .Android会保留进程,以防用户想要重新启动应用程序,这会使启动阶段更快。该过程将不会执行任何操作,如果需要回收内存,则该过程将被终止


    @K_Anas的2美分答案。
    我对finish()方法进行了一个简单的测试。
    列出了活动生命周期中的重要回调方法

  • 在onCreate()中调用finish():onCreate() - > onDestroy()
  • 在onStart()中调用finish():onCreate() - > onStart() - > onStop() - > onDestroy()
  • 在onResume()中调用finish():onCreate() - > onStart() - > onResume() - > onPause() - > onStop() - > onDestroy()
  • 我的意思是说,当执行finish()时,会调用方法的对应部分以及其间的任何方法。

    例如:

    1
    2
    3
     onCreate() counter part is onDestroy()
     onStart() counter part is onStop()
     onPause() counter part is onResume()


    另请注意,如果您在意图后调用finish(),则无法使用"后退"按钮返回上一个活动

    1
    2
    startActivity(intent);
    finish();


    onDestroy()用于最终清理 - 释放您可以自己拥有的资源,关闭开放式连接,读取器,编写器等。如果不覆盖它,系统会执行它所拥有的操作。

    另一方面,finish()只是让系统知道程序员想要完成当前的Activity。因此,它之后会调用onDestroy()

    需要注意的事项:

    只需调用finish()就可以触发对onDestroy()的调用。不,如我们所知,如果感觉需要释放当前Activity所需的资源,android系统可以自由地杀死活动。


    Finish()方法将破坏当前活动。
    如果您不想在用户按下后退按钮时反复加载此活动,则可以使用此方法。
    基本上它会清除当前堆栈中的活动。


    各种答案和注释声称finish()可以跳过onPause()和onStop()并直接执行onDestroy()。公平地说,关于此的Android文档(http://developer.android.com/reference/android/app/Activity.html)注意到"活动正在完成或被系统破坏",这是非常含糊的,但可能暗示finish()可以跳转到onDestroy()。

    完成()上的JavaDoc同样令人失望(http://developer.android.com/reference/android/app/Activity.html#finish())并且实际上没有注意到响应完成时调用了哪些方法()。

    所以我在下面写了这个迷你应用程序,在进入后记录每个州。它包含一个调用finish()的按钮 - 因此您可以看到触发了哪些方法的日志。这个实验表明finish()确实也调用onPause()和onStop()。这是我得到的输出:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    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");
        }

    }


    除了上面的@rommex回答之外,我还注意到finish()确实对Activity的销毁进行了排队,并且它依赖于Activity优先级。

    如果我在onPause()之后调用finish(),我会看到onStop(),并立即调用onDestroy()

    如果我在onStop()之后调用finish(),直到5分钟后才会看到onDestroy()

    根据我的观察,它看起来像是排队等待,当我查看adb shell dumpsys activity activities时它被设置为finishing=true,但由于它不再在前景中,因此没有优先进行破坏。

    总之,onDestroy()永远不会被保证被调用,但即使在它被调用的情况下,它也可能被延迟。


    @ user3282164根据Activity生命周期,它应该在调用finish()时通过onPause() - > onStop() - > onDestroy()

    该图表未显示由系统引起的[活动运行]到[onDestroy()]的任何直接路径。

    onStop()doc说
    "请注意,在内存不足的情况下,可能永远不会调用此方法,在这种情况下,系统没有足够的内存来保持活动进程在调用onPause()方法后运行。"


    我的研究表明,finish()方法实际上在队列中放置了一些销毁操作,但是Activity不会立即被销毁。但是计划进行破坏。

    例如,如果将finish()放在onActivityResult()回调中,而onResume()尚未运行,则将执行第一个onResume(),并且仅在调用onStop()onDestroy()之后。

    注意:根据文档中的说明,可能根本不会调用onDestroy()


    在onCreate()中调用finish不会直接调用onDestroy(),因为@prakash说。在将控制权返回给Android之前,finish()操作甚至不会开始。

    在onCreate()中调用finish():onCreate() - > onStart() - > onResume()。如果用户退出应用程序将调用 - > onPause() - > onStop() - > onDestroy()

    在onStart()中调用finish():onCreate() - > onStart() - > onStop() - > onDestroy()

    在onResume()中调用finish():onCreate() - > onStart() - > onResume() - > onPause() - > onStop() - > onDestroy()

    如需进一步参考,请查看此完成后的连续创建&关于完成()


    到目前为止,似乎唯一正确的答案是由romnex给出的:"onDestroy()可能根本不会被调用"。即使在实践中,几乎在所有情况下都是如此,但不能保证:finish()上的文档仅承诺将活动的结果传播回调用者,但仅此而已。此外,生命周期文档阐明了一旦onStop()完成(或者甚至更早在旧设备上),操作系统就会使活动成为可能,尽管不太可能,因此在一个简单的测试中很难观察到,这可能意味着活动可能会在执行onDestroy()时或甚至在执行onDestroy()之前被杀死。

    因此,如果你想确保在调用finish()时完成一些工作,你不能把它放在onDestroy()中,但是需要在实际调用它之前调用finish()的地方。


    finish()只是发回到android中的上一个活动,或者你可以说它在应用程序中退后一步