Activity.finish()方法到底在做什么?


156

我正在开发Android应用程序一段时间,并关注了很多有关活动生命周期以及应用程序生命周期的文章。

我知道Activity.finish()方法会在到的途中进行调用Activity.onDestroy(),并且还会从堆栈中删除该活动,并且我猜想它以某种方式指向了操作系统和垃圾收集器,他可以“尽其所能”并在发现适当时释放内存所以....

我来到了这篇文章- 退出应用程序会皱眉吗?并阅读Mark Murphy的答案。

这让我对该finish()方法的实际作用感到困惑。

有机会我会打电话finish(),并onDestroy()不会被调用?


Answers:


171

调用finish()活动时,将onDestroy()执行该方法。此方法可以执行以下操作:

  1. 取消活动正在管理的所有对话框。
  2. 关闭活动正在管理的所有游标。
  3. 关闭任何打开的搜索对话框

而且,onDestroy()不是析构函数。它实际上并没有破坏对象。这只是基于特定状态调用的方法。因此,在超类onDestroy()运行并返回之后,您的实例仍然有效并且* .Android会保留进程,以防用户想要重新启动应用程序,这将加快启动阶段。该进程将不执行任何操作,并且如果需要回收内存,则该进程将被终止


5
所以finish()方法仅触发对onDestroy()的调用,仅此而已?
塔尔·卡内尔

9
是的,如果您回到Activity,则会调用onCreate()。
路易斯·佩纳

9
finish()是否还会调用onPause()和onStop()吗?
sr09

36
我再次测试,发现onPause(),onStop()和onDestroy()将在调用finish()之后全部按顺序调用。
Sam003

5
@Laurent onPause()和onStop()并不总是被调用。看到我在下面的答案中观察到的结果
Prakash

77

我在@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()

如果您在onPause内致电完成怎么办?它将调用onStop> onDestroy?
rmpt

该表非常有用且具有描述性(您必须向下滚动一点)developer.android.com/reference/android/app / ...
winklerrr

我本人已证实此答案正确。
Sreekanth Karumanaghat

33

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

startActivity(intent);
finish();

这正是我需要的信息,因为我有一个仅连接到Google Drive的活动,然后进行检查,然后移至主要活动(如果发生错误,则移至“设置”活动),因此用户不应无法回去。
弗朗切斯科·马尔凯蒂-斯塔西

1
@Francesco Marchetti-Stasi在您的情况下,如果用户不应该返回,最好重写onBackPressed()而不在其中调用super.onBackPressed()。
保罗

13

onDestroy()用于最终清理-释放您可以自己使用的资源,关闭打开的连接,读取器,写入器等。如果您不覆盖它,则系统将执行它必须执行的操作。

另一方面,finish()只要让系统知道程序员希望Activity完成电流即可。因此,它onDestroy()在那之后调用。

注意事项:

不必调用来finish()触发对的调用onDestroy()。不。众所周知,如果android系统感觉到当前Activity需要释放一些资源,则可以随意终止活动。


1
您编写了finish()让系统知道需要完成的活动。因此就像说“做x =告诉系统做x”。秒的事情:从您的答案看来,我有一种方法可以调用finish(),系统将决定不调用onDestroy()?可能吗?
Tal Kanel 2012年

您的第一部分正确。呼叫finish()是告诉系统完成Activity。do语句中的“ x”部分是“完成(销毁)Activity”。第二部分是错误的。实际上,我在那里错过了一个字。我已经编辑了答案。onDestroy()不仅由触发finish(),系统也可以自行调用它。
Kazekage Gaara 2012年

1
我刚刚读了您对答案的补充。目前,我已经对答案进行了投票,因为我发现您的解释很有趣,但是在标记为“已回答”之前,我想看看其他人是否还有其他话要说。感谢您现在的时间:)
Tal Kanel 2012年

所以在finish()之后,此活动中的所有变量都将被销毁,对吗?当我再次回到此活动时,它们将被重新声明或初始化,对吗?
西伯斯赌博

3
注意:如果系统终止进程,则可能不会调用onDestroy。 developer.android.com/reference/android/app/...
凯文·李

9

Finish()方法将破坏当前活动。如果您不希望在用户按下“后退”按钮时一次又一次地加载此活动,则可以使用此方法。基本上,它清除当前堆栈中的活动。


8

除了上面的@rommex答案外,我还注意到finish()确实将活动的销毁排入队列,这取决于活动的优先级。

如果我finish()在之后打电话onPause(),我看到了onStop(),然后onDestroy()立即打电话。

如果我finish()在之后致电onStop()onDestroy()则要等5分钟后才能看到。

从我的观察来看,完成似乎在排队,当我将adb shell dumpsys activity activities其设置为时finishing=true,但是由于它不再位于前台,因此没有优先考虑进行销毁。

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


5

各种答案和注释都声称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()实际上确实也调用了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");
    }

}

3

@ user3282164根据活动生命周期,应在调用时经历onPause()-> onStop()-> 。onDestroy()finish()

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

onStop()文档说:“ 请注意,在内存不足的情况下,如果系统没有足够的内存来保持您的活动的进程在调用其onPause()方法后仍在运行,则可能永远不会调用此方法。



2

我的研究表明,该finish()方法实际上在队列中放置了一些销毁操作,但是没有立即销毁Activity。虽然销毁是预定的。

例如,如果您放置finish()onActivityResult()回调中,而onResume()尚未运行,则将首先onResume()执行,只有在之后onStop()onDestroy()调用。

注意:onDestroy()可能根本没有被调用,如文档中所述


2

在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()

更多参考检查看看这个OnCreate中连续完成后大约完成()


0

到目前为止,似乎唯一正确的答案是romnex给出的:“可能根本不调用onDestroy()”。即使在实践中,几乎在所有情况下都不能保证:finish()上的文档仅保证将活动结果传播回调用方,但仅此而已。此外,生命周期文档还阐明,onStop()完成时(或在较早的设备上更早),操作系统可以终止该活动,尽管这不太可能,因此在简单测试中很少发现,但这可能意味着该活动在执行onDestroy()之前或什至之前可能会被杀死。

因此,如果要确保在调用finish()时完成某些工作,则不能将其放在onDestroy()中,而需要在实际调用它之前,在调用finish()的位置进行。


-4

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.