1. 程式人生 > >Android總結篇系列:Activity生命週期

Android總結篇系列:Activity生命週期

Android官方文件和其他不少資料都對Activity生命週期進行了詳細介紹,在結合資料和專案開發過程中遇到的問題,本文將對Activity生命週期進行一次總結。

Activity是由Activity棧進管理,當來到一個新的Activity後,此Activity將被加入到Activity棧頂,之前的Activity位於此Activity底部。Acitivity一般意義上有四種狀態:

1.當Activity位於棧頂時,此時正好處於螢幕最前方,此時處於執行狀態

2.當Activity失去了焦點但仍然對用於可見(如棧頂的Activity是透明的或者棧頂Activity並不是鋪滿整個手機螢幕),此時處於暫停狀態

3.當Activity被其他Activity完全遮擋,此時此Activity對使用者不可見,此時處於停止狀態

4.當Activity由於人為或系統原因(如低記憶體等)被銷燬,此時處於銷燬狀態;

在每個不同的狀態階段,Adnroid系統對Activity內相應的方法進行了回撥。因此,我們在程式中寫Activity時,一般都是繼承Activity類並重寫相應的回撥方法。

 

圖中詳細給出了Activity整個生命週期的過程,以及在不同的狀態期間相應的回撥方法。

圖中需要注意一下幾點:

1.Activity例項是由系統自動建立,並在不同的狀態期間回撥相應的方法。一個最簡單的完整的Activity生命週期會按照如下順序回撥:onCreate -> onStart -> onResume -> onPause -> onStop -> onDestroy。稱之為entire lifetime。

2.當執行onStart回撥方法時,Activity開始被使用者所見(也就是說,onCreate時使用者是看不到此Activity的,那使用者看到的是哪個?當然是此Activity之前的那個Activity),一直到onStop之前,此階段Activity都是被使用者可見,稱之為visible lifetime。

3.當執行到onResume回撥方法時,Activity可以響應使用者互動,一直到onPause方法之前,此階段Activity稱之為foreground lifetime。

在實際應用場景中,假設A Activity位於棧頂,此時使用者操作,從A Activity跳轉到B Activity。那麼對AB來說,具體會回撥哪些生命週期中的方法呢?回撥方法的具體回撥順序又是怎麼樣的呢?

開始時,A被例項化,執行的回撥有A:onCreate -> A:onStart -> A:onResume。

當用戶點選A中按鈕來到B時,假設B全部遮擋住了A,將依次執行A:onPause -> B:onCreate -> B:onStart -> B:onResume -> A:onStop。

此時如果點選Back鍵,將依次執行B:onPause -> A:onRestart -> A:onStart -> A:onResume -> B:onStop -> B:onDestroy。

至此,Activity棧中只有A。在Android中,有兩個按鍵在影響Activity生命週期這塊需要格外區分下,即Back鍵和Home鍵。我們先直接看下實驗結果:

此時如果按下Back鍵,系統返回到桌面,並依次執行A:onPause -> A:onStop -> A:onDestroy。

此時如果按下Home鍵(非長按),系統返回到桌面,並依次執行A:onPause -> A:onStop。由此可見,Back鍵和Home鍵主要區別在於是否會執行onDestroy。

此時如果長按Home鍵,不同手機可能彈出不同內容,Activity生命週期未發生變化(由小米2s測的,不知道其他手機是否會對Activity生命週期有影響)。

由於Android本身的特性,使得現在不少應用都沒有直接退出應用程式的功能,按照一般的邏輯,當Activity棧中有且只有一個Activity時,當按下Back鍵此Activity會執行onDestroy,那麼下次點選此應用程圖示將從重新啟動,因此,當前不少應用程式都是採取如Home鍵的效果,當點選了Back鍵,系統返回到桌面,然後點選應用程式圖示,直接回到之前的Activity介面,這種效果是怎麼實現的呢?

通過重寫按下Back鍵的回撥函式,轉成Home鍵的效果即可。

@Override
public void onBackPressed() {
    Intent home = new Intent(Intent.ACTION_MAIN);
    home.addCategory(Intent.CATEGORY_HOME);
    startActivity(home);
}

當然,此種方式通過Home鍵效果強行影響到Back鍵對Activity生命週期的影響。注意,此方法只是針對按Back鍵需要退回到桌面時的Activity且達到Home效果才重寫。

或者,為達到此類效果,Activity實際上提供了直接的方法。

1 activity.moveTaskToBack(true);

moveTaskToBack()此方法直接將當前Activity所在的Task移到後臺,同時保留activity順序和狀態。

在之前的專案開發過程中,當時遇到一個很奇怪的問題:手機上的“開發者選項”中有一個“不保留活動”的設定,當開啟此設定,手機上的設定提示是“使用者離開後即銷燬每個活動”,開啟後,對於其他的應用程式是從A Acticity到B Activity,然後Back鍵回到A,此時,其他應用程式只是先白屏(有可能黑屏等,取決於主題設定)一下,然後A開始可見,但是我的應用程式中出現的一個結果卻是直接返回到了桌面。一開始百思不得其解。最後終於定位出問題。首先,我們需要明確開啟此設定項後對Activity生命週期的影響。開啟此設定項後,當A到B時,假設B全部遮擋住了A,將依次執行A:onPause -> B:onCreate -> B:onStart -> B:onResume -> A:onStop -> A:onDestroy。是的,A在系統原本的生命週期回撥中增加了onDestroy。此即“使用者離開後即銷燬每個活動”的含義。但此時需要注意的是,只要沒有認為的呼叫A的finish()方法,雖然A執行了onDestroy,但Activity棧中依然保留有A,此時B處於棧頂。那麼在B中按Back鍵回到A時,將依次執行:B:onPause -> A:onCreate -> A:onStart -> A:onResume -> B:onStop -> B:onDestroy。沒錯,A從onCreate開始執行了。此處也就解釋了為什麼A可能會出現白屏(或黑屏等)一下的原因了。

那麼為什麼我的應用程式會跟其他應用程式出現不一樣呢?最後定為出問題在於當時我的應用程式中為了做到完全退出應用程式效果,專門使用了一個Activity棧去維護Activity(當時是借鑑了網上的此類實現方案,現在想想,實在沒必要,且不說Android本身特性決定了沒必要通過如此方法去達到退出效果,僅僅是此方法本身也存在很大的問題,現在在網上依然能見到有不少文章說到應用程式退出可以使用此方法,哎。。),在onCreate中入棧,onDestroy出棧,呼叫瞭如下方法

1 // 結束Activity&從堆疊中移除
2 AppManager.getAppManager().finishActivity(this);

其中,AppManager中finishActivity函式具體定義是:

複製程式碼
 1 /**
 2  * 結束指定的Activity
 3  */
 4 public void finishActivity(Activity activity) {
 5     if (activity != null) {
 6         activityStack.remove(activity);
 7         activity.finish();
 8         activity = null;
 9     }
10 }
複製程式碼

至此,相信大家應該看出問題的所在了吧。

沒錯,問題在於執行了activity的finish()方法!! activity的finish()方法至少有兩個層面含義,1.將此Activity從Activity棧中移除,2.呼叫了此Activity的onDestroy方法。對於不開啟“不保留活動”的設定項,實際上也沒什麼影響,但是一旦開啟此設定,問題顯露無疑。開啟此此設定後,正常情況下離開A,即使執行了A的onDestroy,Activity棧中還是有A的,但是我這樣寫後,finish()方法一執行,Activity棧中就沒有A了,因此,當點選Back鍵時,Activity棧中已經沒有此應用的任何Activity了,直接來到了手機桌面。

可能,有些人會說,我就是要通過此種方法想去完全退出應用程式,同時希望自己的Activity棧和系統中Activity棧保持一致,怎麼辦呢?

在此,可以通過如下改寫去實現:

複製程式碼
/**
* 結束指定的Activity
 */
public void finishActivity(Activity activity) {
    if (activity != null) {
    // 為與系統Activity棧保持一致,且考慮到手機設定項裡的"不保留活動"選項引起的Activity生命週期呼叫onDestroy()方法所帶來的問題,此處需要作出如下修正
    if(activity.isFinishing()){
        activityStack.remove(activity);
        //activity.finish();
        activity = null;
    }
    }
}
複製程式碼

轉自:http://www.cnblogs.com/lwbqqyumidi/p/3769113.html

相關推薦

Android總結系列Activity生命週期

Android官方文件和其他不少資料都對Activity生命週期進行了詳細介紹,在結合資料和專案開發過程中遇到的問題,本文將對Activity生命週期進行一次總結。 Activity是由Activity棧進管理,當來到一個新的Activity後,此Activity將被加入到Activity棧頂,之前的A

Android總結系列Android Service

1 public class CActivity extends Activity { 2 3 public static final String TAG = "CActivity"; 4 5 private Button bindServiceBtn;

Android總結系列Android廣播機制----學習

1.Android廣播機制概述Android廣播分為兩個方面:廣播發送者和廣播接收者,通常情況下,BroadcastReceiver指的就是廣播接收者(廣播接收器)。廣播作為Android元件間的通訊方式,可以使用的場景如下:1.同一app內部的同一組件內的訊息通訊(單個或多

_048_Android_Android總結系列Android Service

轉自https://www.cnblogs.com/lwbqqyumidi/p/4181185.html,感謝作者的無私分享。 Service通常總是稱之為“後臺服務”,其中“後臺”一詞是相對於前臺而言的,具體是指其本身的執行並不依賴於使用者可視的UI介面,因此,從實際業務需求上來理解,Serv

androidActivity-生命週期

2、可見的生命週期,從onStart()開始到onStop()結束。在這段時間,可以看到Activity在螢幕上,儘管有可能不在前臺,不能和使用者互動。在這兩個介面之間,需要保持顯示給使用者的UI資料和資源等,例如:可以在onStart中註冊一個IntentReceiver來監聽資料變化導致UI的變動,當不再

AndroidActivity——生命週期深入詳解

一、生命週期全面分析Android活動預設執行在當前程序所擁有的棧中,前臺可見的活動則在活動棧的最頂部。其他後臺活動則在棧的裡面,在正常的情況下(記憶體充足)其他的活動並沒有被回收或者殺死,它們仍然存在於棧中保持著原來的狀態。當前面的活動退出後,後面的活動就會搬到前臺使得被使

Android問題Activity生命週期事件

四狀態:活躍、暫停、停止、銷燬。 當Android中Activity在執行的時候,Activity的活動狀態由Android和Activity棧的形式管理。當前活動的Activity位於棧頂。 隨著不同應用的執行,每個Activity都可能在活動狀態和非活動狀態之間切換。

Android基礎Activity生命週期細化

一、   細化Activity的生命週期         在進行Android應用開發的時候,需要考慮如何使用Activity的生命週期中的方法使得程式符合使用者的期望且在activity不需要的時候不會導致系統資源的浪費。下面從activity的啟動和銷燬、暫停和恢復、

Java總結系列Java多線程(二)

文章 睡眠 blog setdeamon java多線程 cep public pan level Java總結篇系列:Java多線程(二) 本文承接上一篇文章《Java總結篇系列:Java多線程(一)》。 四.Java多線程的阻塞狀態與線程控制 上文已經提到Jav

Java總結系列Java多線程(一)

常見 而是 同時 private 狀態 過程 運行時 不同的 bstr Java總結篇系列:Java多線程(一) 多線程作為Java中很重要的一個知識點,在此還是有必要總結一下的。 一.線程的生命周期及五種基本狀態 關於Java中線程的生命周期,首先看一下下面這張較

Java總結系列Java泛型

ech internal clone 傳遞 sta 是什麽 dom bar 依然 一. 泛型概念的提出(為什麽需要泛型)? 首先,我們看下下面這段簡短的代碼: 1 public class GenericTest { 2 3 public static

Android核心技術-day06-05-Activity生命週期,應用場景

package com.gaozewen.lifecycle; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import an

設計模式總結系列建造者模式(Builder)

關於建造者模式網上有很多文章,也有些不同的理解。在此結合網上其他文章對建造者模式進行總結。 總體說來,建造者模式適合於一個具有較多的零件(屬性)的產品(物件)的建立過程。根據產品建立過程中零件的構造是否具有一致的先後順序,可以將其分為如下兩種形式。 一、通過Client、Director、Builder和

Android課程(1.3 activity生命週期

可以在SDK安裝路徑下docs /裡查詢到類檔案的文件 onCreate() onStart():當Activity可以被我們看到 則呼叫該方法 onResume()當Activity可以獲得使用者焦點的時候呼叫該方法。可以在該Activity進行

Java總結系列Java String

1 public static main([Ljava/lang/String;)V 2 L0 3 LINENUMBER 5 L0 4 LDC "aa" 5 ASTORE 1 6 L1 7 LINENUMBER 6 L1 8 LDC "bb" 9

android橫豎屏切換,activity生命週期方法是否會回撥

預設情況下的一個應用,沒有在androidmainfest檔案進行任何設定一切都是預設的情況下,我們當改變了他的orientation時候是會銷燬當前activity,新建一個新的activity public void orien(View view)

設計模式總結系列外觀模式(Facade)

張三自從畢業後開始做軟體開發,做著做著發現不爽了,錢賺不了太多,頭髮也白了。於是拿著一點小資本,想著做點小生意。瞅著眼前的餐飲行業還不錯,於是打算開一家餐館。開參觀可不是一件容易的事,僅僅行政類的審批流程就不少。至少包括辦理衛生許可證,辦理稅務登記,辦理工商登記等。 我們

android-----橫豎屏切換對Activity生命週期的影響

       前面我們分析過Activity的生命週期(見:android-----Activity生命週期),但是在現實應用中我們可能會對手機進行橫豎屏切換,那麼這樣的切換對Activity的生命週

Java總結系列Java多執行緒(四)

多個執行緒同步執行ping ip示例package com.ebao.pojo;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import j

Android 開發(六)Activity生命週期以及函式意義

簡述:   1.在日常應用中Activity是與使用者互動的介面,它提供了一個使用者完成相關操作的視窗。當我們在開發中建立Activity後,通過呼叫setContentView(View)方法來給該Activity指定一個佈局介面,而這個介面就是提供給使用者互動的介面。Androi