繁体   English   中英

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

[英]What is Activity.finish() method doing exactly?

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

我知道Activity.finish()方法调用中的某处方式Activity.onDestroy()并去除叠活动,我想它在某种程度上点,操作系统和垃圾收集器,他可以“做他的绝招”,并免费当它找到它的好时机这样做的记忆......

我来到这篇文章 - 退出申请是否令人不悦? 并阅读马克墨菲的回答。

这让我对finish()方法究竟做了什么感到有些困惑。

有没有可能我会调用finish()而不会调用onDestroy()

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

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

此外, onDestroy()不是析构函数。 它实际上并没有破坏对象。 它只是一种基于特定状态调用的方法。 因此,在超类的onDestroy()运行并返回之后,您的实例仍然处于活动状态并且非常好*。Android 会保留进程以防用户想要重新启动应用程序,这使得启动阶段更快。 该进程不会做任何事情,如果需要回收内存,该进程将被杀死

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

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

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

startActivity(intent);
finish();

onDestroy()用于最终清理 - 释放您自己可以使用的资源,关闭打开的连接、读取器、写入器等。 如果你不覆盖它,系统就会做它必须做的事情。

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

需要注意的一点:

没有必要调用finish()触发调用onDestroy() 不可以。我们知道,android 系统如果觉得有当前Activity需要的资源需要释放,则可以自由地杀死Activity

Finish() 方法将销毁当前活动。 如果您不希望在用户按下后退按钮时一次又一次地加载此活动,您可以使用此方法。 基本上它会从 .current 堆栈中清除活动。

除了上面的@rommex 回答之外,我还注意到finish()确实将 Activity 的销毁排入队列,并且它取决于 Activity 的优先级。

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

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

根据我的观察,看起来完成排队,当我查看adb shell dumpsys activity activities它被设置为finishing=true ,但由于它不再在前台,因此没有优先销毁。

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

各种答案和笔记都声称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");
    }

}

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

该图没有显示由系统引起的从 [Activity Running] 到 [ onDestroy() ] 的任何直线路径。

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

我的研究表明, finish()方法实际上在队列中放置了一些销毁操作,但该 Activity 并没有立即销毁。 不过销毁是按计划进行的。

例如,如果您将finish()放在onActivityResult()回调中,而onResume()尚未运行,则将首先执行onResume() ,然后再onStop()onDestroy()

注意:如文档中所述,可能根本不会调用onDestroy()

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

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

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

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

如需进一步参考检查,请查看此oncreate 连续完成后关于完成()

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

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

Roomex 说得对!

发生在我身上的是我正在开发一个需要我使用蓝牙侦听器类的应用程序。 主页上的一个 Fragment 调用了一个同样使用 BluetoothListner 类的活动。 我使用startActivityForResult()方法来获得确认。 问题是在尝试侦听蓝牙端口时获得片段的确认后,活动通道仍然处于活动状态。 即使我专门关闭了它onDestroy()方法。 我花了好几天,但不知道如何停止。

我想如果我不使用startAcivityForResult()而只使用startActivity()和不使用调用的finish()方法可能会解决这个问题。 当然,如果我确实在片段内调用了finish() ,则必须从活动中调用带有导航视图的 MainActivity 并指向该片段。 这样它就有可能创建一个全新的 MainActivity 实例。 或者在调用 Activity 时不使用finish()onDestroy()方法将为活动调用,一旦我们返回到它,片段的onResume()方法将被调用。

完成()只是发送回android中的前一个活动,或者您可以说它在应用程序中退后一步

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM