簡體   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