1. 程式人生 > >Activity不同情況下生命週期

Activity不同情況下生命週期

想要徹底弄清楚Activity在不同情況下的生命週期需要先掌握Activity的一些基礎知識

Activity完整的生命週期如下圖:

生命週期流程圖
知道了Activity完整的生命週期之後還需要知道Activity的啟動模式。

Activity四種啟動模式:

  • standard:
    預設的啟動模式,每次通過這種模式啟動目標Acitivity,都建立一個新的例項,並將該Activity新增到當前棧頂。

  • singleTop:
    只有當Activity位於棧頂時,系統才不會重新建立目標Activity的例項,而是直接複用已有的Activity例項。否則建立一個新的例項。這種模式經常被用在新聞展示頁,當推送過來一條新聞,跳轉到新聞頁顯示,如果你正在看新聞,就不需要重複的建立這個activity

  • singleTask:
    如果棧中不存在目標Activity時,則建立目標Activity例項。
    如果棧中存在目標Activity時,
    (1)已經位於棧頂,此時與singleTop行為相同
    (2)不位於棧頂,系統會使該Activity上面所有的Activity出棧。

  • singleInstance:
    如果棧中不存在目標Activity,系統會建立一個新的任務棧,再建立Activity例項,將它加入該棧中
    如果棧中存在該Activity,無論哪個應用程式呼叫,都不會建立新的Activity

舉例

假設有兩個Activity A、B

  1. standard模式
    當A啟動到從A跳轉到B的生命週期
    A啟動時:onCreate -> onStart -> onResume
    從A跳轉到B時:A.onPause -> B.onCreate -> onStart -> onResume -> A.onStop
    按back鍵返回時:B.onPause -> A.onReStart -> onStart -> onResume -> B.onStop -> onDestroy
  2. singleTop模式
    設定A為singleTop,啟動A,從A跳A,就是在棧頂時會不會建立A的例項
    A啟動時:onCreate -> onStart -> onResume
    從A跳A時:onPause -> onResume
    按back鍵返回時:onPause -> onStop -> onDestroy
    可以看到並沒有重新建立A的例項,只是執行了onPause 和onResume
  3. singleTask模式
    設定A為singleTask,啟動A,從A跳B,再從B跳A
    A啟動時:onCreate -> onStart -> onResume
    從A跳轉到B時:A.onPause -> B.onCreate -> onStart -> onResume -> A.onStop
    從B跳轉到A時:B.onPause -> A.onReStart -> onStart -> onResume -> B.onStop -> onDestroy
    可以看到當A在棧中存在時,再次跳轉不會建立A的例項並使A上面的B出棧
  4. singleInstance模式
    為 singleInstance 模式時,activity獨佔一個task,現在有以下三個activity: Act1、Act2、Act3,其中Acti2 為 singleInstance 模式。它們之間的跳轉關係為: Act1 – Act2 – Act3 ,現在在Act3中按下返回鍵,由於Act2位於一個獨立的task中,它不屬於Act3的上下文activity,所以此時將直接返回到Act1,Act1再按下返回鍵時到Act2,這就是singleInstance模式。

看完四種模式,這裡會有疑問:

為什麼要先執行A的onPause方法,再執行B的生命週期方法?
為什麼不是執行完A的onStop方法之後再執行B的生命週期方法?

首先來看第一個問題,假如A正在播放一段音樂,如果先執行B的生命週期,再執行A的onPause方法,就會出現B已經顯示出來,A中的音樂還在播放的異常情況。而如果先執行了A的onPause方法,我們就可以在其中執行一些操作來暫停音樂的播放。原本onPause方法的設計職責即使如此。
對於第二個問題,由於Activity的可見生命週期是onStart()到onStop(),假如先執行A的onPause()和onStop(),再執行B的生命週期,每次切換的時候就會出現黑屏的情況,這種切換效果顯然是不優雅的。

注:

  • 建議在onCreate()中呼叫setContentView()、findViewById()
  • 建議在onResume()中開啟獨佔裝置(比如相機)、開啟動畫等
  • 建議在onPause()中執行關閉獨佔裝置、停止動畫等比較耗CPU的操作,但不要執行比較耗時的操作,底層執行Activity的onPause()時,有一定的時間限制的,當ActivityManagerService通知應用程序暫停指定的Activity時,如果對應的onPause()在500ms內還沒有執行完,ActivityManagerService就會強制關閉這個Activity。
  • onStop()中可以執行一些比較耗時的操作,這是在後臺執行所以也不影響使用者的體驗

附:
伴隨著activity常用的除了生命週期還有兩個方法,onSaveInstanceState 和 onNewIntent

1.onSaveInstanceState
我們都知道不同的手機,記憶體不同,系統在記憶體不足的時候很有可能就會把你APP中不再棧頂的activity給回收掉。如果這個activity無關緊要那就啥也不說了,但是就怕它對你來說很重要。這個時候你不對它進行保護措施的話,你就等著哭吧。比如你打開了A,A是一個註冊類activity。然後你填寫了一堆資訊後,返回桌面去看了一條簡訊,或者接了一個電話,等你再開啟這個的時候你發現裡面填寫的東西都不見了,這個時候你想不想一巴掌拍死這個開發人員?

所以呢onsaveinstancestate()就可以閃亮登場了,雖然你也可以使用其他儲存機制去處理,但是對於這種情況,onsaveinstancestate()依然是最佳的選擇。onsaveinstancestate()方法有的同學有可能沒見過 但是savedinstancestate相必都見過,就是在oncreate()方法的那個括號裡面,savedinstancestate是一個bundle型別的引數,bundle有很多儲存資料的方法這個你想必是知道的吧,對我們就是利用這個去儲存資料。onsaveinstancestate()回撥方法會保證一定在activity被回收之前呼叫

onSaveInstanceState方法會在什麼時候被執行,有這麼幾種情況:

  • 當用戶按下HOME鍵時。
  • 長按HOME鍵,選擇執行其他的程式時。
  • 按下電源按鍵(關閉螢幕顯示)時。
  • 從activity A中啟動一個新的activity時。
  • 螢幕方向切換時,例如從豎屏切換到橫屏時。

當按下HOME鍵或者鎖屏時,會執行onPause -> onSaveInstanceState -> onStop
當從activity A跳轉到 B 時,A.onPause -> B.onCreate -> onStart -> onResume -> A.onSaveInstanceState -> A.onStop

使用:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_one);
        if (savedInstanceState != null) {
            String oldString = savedInstanceState.getString("Activity");
            Log.e(TAG,"oldString="+oldString);
        }
        Log.e(TAG,"onCreate");
    }

@Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.e(TAG,"onSaveInstanceState");
        String string = "activity 被系統回收了怎麼辦?";
        outState.putString("Activity", string);
    }

2.onNewIntent
如果activity設定為singleTask或者signleTop模式【當呼叫startActivity方法時,這兩種模式不會重新建立activity,只會呼叫onNewIntent方法,當然任務棧中沒有銷燬該activity的情況下】,再向activity傳值時,就可以利用onNewIntent
執行順序:onNewIntent -> onReStart -> onStart -> onResume

@Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.e(TAG,"onNewIntent");
        setIntent(intent);
        String msg = getIntent().getExtras().getString("msg");
        Log.e(TAG,"msg="+msg);
    }

//另一個activity中傳送
 Intent intent = new Intent(this,OneActivity.class);
 intent.putExtra("msg","傳值過來");
 startActivity(intent);

相關推薦

Activity不同情況生命週期

想要徹底弄清楚Activity在不同情況下的生命週期需要先掌握Activity的一些基礎知識 Activity完整的生命週期如下圖: 知道了Activity完整的生命週期之後還需要知道Activity的啟動模式。 Activity四種啟動模式:

兩個Activity切換時的生命週期

兩個Activity切換時的生命週期: 舊Activity記為ActivityOld,新Activity記為ActivityNew,從舊Activity開啟新Activity開始記錄: ActivityOld#onPause() ActivityNew#onCreate() Ac

Java中不同情況的執行順序整理:

      初始化順序:父靜態變數、父靜態程式碼塊、子類靜態變數、子類靜態程式碼塊、父類非靜態變數、父類非靜態程式碼塊、父類構造器、子類非靜態變數、子類非靜態程式碼塊、子類建構函式。       執行順序:父類B靜態程式碼塊->子類A靜態程式碼塊->父類B非靜態

Activity與Fragment的生命週期詳解

在安卓中Activity與Fragment是非常相似的兩個類,它們各自都擁有自己的生命週期,且都可以用來顯示佈局檔案中的檢視。其中Activity是通過setContenView()顯示檢視,而Fra

Android測試Activity和Fragment的生命週期

Activity的生命週期有7個函式,Fragment的生命週期有11個函式。 Activity生命週期除上述6個方法還有一個Restart()方法,該方法在該Activity從不可見(仍存在)到重新可見時呼叫。 測試程式碼如下: import android.a

有關Service的startService與bindService在各種情形生命週期的變化

Activity模版: public class MainActivity extends AppCompatActivity{ private ServiceConnection connection=new ServiceConnection

Activity與Fragment的生命週期

一、Activity 生命週期 二、Fragment 生命週期 三、對比圖 四、測試程式碼 package com.goso.testapp; import android.app.Activity; import android.app.ListFragmen

Activity與Fragment 的生命週期對比

Fragment是3.0以後的東西,為了在低版本中使用Fragment就要用到android-support-v4.jar相容包,而FragmentActivity就是這個相容包裡面的,它提供了操作Fragment的一些方法,其功能跟3.0及以後的版本的Acti

Activity#finish() 對其生命週期的影響

如果在 Activity#onCreate() 方法中呼叫 finish() 方法,其生命週期會發生什麼變化? 實驗環境: compilesdksion=25.0.3; com.android.support:appcompat-v7:25.3.1

activity透明主題引起生命週期的變化

以前開發時,一直沒有留意activity如果主題背景透明,對生命週期有什麼影響呢? 測試方式:編寫demo 配置檔案(AndroidManifest)中 <?xml version="1.0" encoding="utf-8"?> <

Activity和Fragment的生命週期執行順序

總結一下Activity和Fragment的生命週期:  1.Activity和Fragment啟動時候的生命週期  1.Activity super.onCreate執行完畢.- Fragment

不同情況request.getContextPath()值的區別

經常使用request.getContextPath(),但對它的具體作用有時還是不太明白。其實它的作用是獲取當前的系統路徑。 比如,如果使用Tomcat作為伺服器部署專案,一般將專案部署到webapps下(當然,也有可能是wtpwebapps,詳細可見我

兩個Activity跳轉時 生命週期函式的變化

Activity 的生命週期: 生命週期函式呼叫時機 onCreate 在Activity物件被第一次建立時呼叫 onStart當Activity 變得可見是呼叫該函式 onResume當Activity開始準備與使用者互動時呼叫該方法 onPause當系

Spring bean在不同情況的預設id或name 侵立刪

轉自:https://www.cnblogs.com/1540340840qls/p/6962777.html bean如果不知名id是什麼它一般都有一個id或者講名字。第一種情況:元件掃描的情況:預設的id號或者bean的name是類名的首字母小寫。程式碼如下: 1 pac

各種常見場景Activity生命週期

1. Activity正常啟動: onCreate -> onStart -> onResume 2. Activity啟動另一個Activity: (1)B完全遮擋住A A:onPause -> B:onCreate -> B:onStart

Android拉通知欄會影響Activity生命週期方法嗎?

很好奇,下拉通知欄會影響Activity的生命週期方法嗎? 在Activity的方法裡面加上呼叫的Log public class MainActivity extends AppCompatA

activity異常情況生命週期的分析

當系統配置發生改變後,activity會被銷燬,其onpause,onstop,ondestory均會被呼叫,同時由於activity是異常終止的,系統會呼叫onsaveinstancestate來儲存當前activity的狀態,這個方法的呼叫時機是onstop之前,它和onpause沒有既定的時序觀念,有可

Android8.0切換橫豎螢幕時Activity生命週期

一、前言 看了一些關於切換螢幕時Activity生命週期變化的部落格,初步理解了切換螢幕時的變化過程(私以為,預設情況下之所以切換橫豎屏時會重新載入活動,是為了更好的使用者體驗哈哈)。但是因API版本號以及收集型號的不一樣,這個過程都會略有不同。——————&

Activity生命週期的回撥,你應該知道得更多!--Android原始碼剖析(

private void handleBindApplication(AppBindData data) { mBoundApplication = data; mConfiguration = new Configuration(data.co

activity在singleTop模式生命週期

設計三個activity:act1,act2,act3;我們在配置檔案中將三個act都可以設定為singleTop,通過相互或自身跳轉來熟悉這種模式的特點。首先我們的執行順序為:act1->act2->act3->act1->act2->act3