Android基礎部分再學習---activity的生命周期


關於activity的生命周期:要知道的知識點

1.每個生命活動執行的順序、

2.每個生命周期我們應該做怎么樣的處理:每個方法保留的時間有多久;那個方法是活動阻塞的,他沒有做完,別的人做不了;那個方法讓我們暫時回收內存,避免內存泄露等等

3.我們怎么強制性關閉activity

4.生命周期的設計模式,(模板方法模式),我們可以重寫他的每個活動的方法


1.執行順序


這種順序已經很熟悉了,網上有人也對這個生命周期進行了另外的解說:分為可見和不可見,運行狀態來區分生命周期,

1、entire lifetime (整個生命周期)

一個Activity整個生命周期,存在於onCreate()方法和onDestroy()調用之間。你的Activity應該在onCreate()方法里執行設置“全局”狀態(如定義布局)。並在onDestroy()方法里釋放所有剩余資源。例如,如果你的活動有一個線程在后台運行下載網絡數據,它可以在onCreate()中創建該線程【一般在onStart里面創建更好子線程,主要是onCreate()只有5秒的響應時間】,然后在onDestroy()中停止線程。

2、visible lifetime(可見生命周期)

一個Activity可見生命周期,存在於onStart()和onStop()調用之間。在此期間,用戶可以看到屏幕上的activity並與之交互。當一個其他的Activity啟動,並且這個Activity完全不可見的時候,onStop()方法就會被調用。在這兩個方法,你可以保持該Activity需要展示給用戶的資源。例如,您可以在onStart()方法里注冊一個BroadcastReceiver來監控你的UI的變化,並在onStop()方法里注銷它。在整個生命周期的活動中,系統可能會調用onStart()和onStop()多次,因為活動之間交替進行隱藏或顯示給用戶。

3、 foreground lifetime(前台生命周期)

一個Activity前台生命周期,存在於onResume()和onPause()調用之間。在這段時間里,這個Activity在其他所有Activity的前面,擁有用戶輸入焦點。一個Activity可以經常在前台狀態發生轉換—比如,當設備休眠或者彈出了個對話框。因為經常會發生轉換,所以在這兩個方法之間的代碼應該是輕量級的,防止導致其他轉換變慢使得用戶需要等待。


一個Activity本質上只有三種狀態:

Resumed(運行)、Paused(暫停)、Stopped(停止),因為從Activity被創建之后,它只可能在這三種狀態保持長久的停留,其他的回調方法結束后的狀態都只能稱之為過渡狀態。比如進入到onStart方法后,執行完該方法,會立即進入到OnResume方法。(這里所說的狀態都是指對應的某個方法返回之后)


即使一個Activity進入到Paused或者Stopped方法,它仍然是存在的,被保存在任務返回堆棧中。它仍然保持着自身的所有實例和狀態,所以根本不用擔心它在返回到onResume方法時,實例會變為null,或者控件的事件監聽不了(我以前就擔心過這個問題)。唯一需要考慮的就是,系統在內存不足的情況下,殺死在Paused或者Stopped狀態下的Activity。

當一個Activity在Resumed狀態下,它是不會因內存不夠而被系統直接殺死(在極端的情況下也有可能被殺死,但是一般不會考慮這種情況)。只有進入Paused或者Stopped狀態才會,而且可能根本就不會去調用onStop()和onDestory()方法,所以onPause()方法是我們最大程度上保證Activity在銷毀之前能夠執行到的方法。【這也就導致了我們可以在onPause()方法里面用isFinshing()方法來判斷activity還在不在,onPause方法是Activity創建后最有可能保證執行的方法】因此,如果你的某個Activity需要保存某些數據到數據庫,您應該在onPause()里編寫持久化數據的代碼。但要注意,你應該選擇哪些信息必須保留在onPause(),因為這個方法任何阻塞程序都會阻止過渡到下一個Activity,這樣給用戶體驗就感覺十分緩慢。【這個里面一定不能太耗時,否則會阻塞,影響用戶體驗,onPause里面保存的數據是可能保存到硬盤去的,因為他是用bundle進行管理的,bundle是由系統來管理的


關於視圖可見的問題:

onPause() 執行之后,如果是跳轉到另外一個activity,比如是A跳到B,A執行onPause(),然后就執行B的onCreate(),onStart(),onResume(),最后才執行A的onStop(),從這個流程看來,onPause其實是可見不可觸發的一種狀態,就是界面還是有的,但是用戶無法點擊了,然后去執行B的創建過程,顯示視圖了,A就轉到后台生命周期里面去了,


onResume是視圖可見可操作的,

onCreate()方法是不可見也不可以操作,還要注意一點,View的繪制過程是在onCreate執行完之后,

onStart()方法是可見但是不可以操作


finish方法的問題:

當你在onClick事件里面寫 startacitivity的時候,在前面執行finish方法和在后面執行finish方法,他們影響不大,因為他們都是異步的過程

他會把所有的異步代碼全部執行了,然后再去執行startActivity():onpause,另一個activity的創建過程,然后是onstop,ondestroy(),

並且startActivity先於finish解除阻塞


2.在各個生命周期中,我們能做些什么事

回調方法的作用,就是通知我們Activity生命周期的改變,然后我們可以處理這種改變,以便程序不會崩潰或者數據丟失等等,也就是擁有更好的用戶體檢,那么這么多回調方法里到底應該怎么做呢?

這個問題不好總結,因為不同的應用、不同的Activity所干的事都不一樣,有時候我們甚至只需要實現一個onCreate就行了。所以下面所說的,看看即可,不一定符合所有的情況。

1、onCreate

最重要是在里面調用setContentView,還可以在里面初始化各控件、設置監聽、並初始化一些全局的變量。

因為在Activity的一次生命周期中,onCreate方法只會執行一次。在Paused和Stopped狀態下恢復或重啟的下,這些控件、監聽和全局變量也不會丟失。即便是內存不足,被回收了,再次Recreate的話,又是一次新的生命周期的開始,又會執行onCreate方法。


還可以在onCreate執行數據操作,比如從Cursor中檢索數據等等,但是如果你每次進入這個Activity都可能需要更新數據,那么最好放在onStart里面。(這個需要根據實際情況來確定)


2、onDestory

確定某些資源是否沒有被釋放,做一些最終的清理工作,比如在這個Activity的onCreate中開啟的某個線程,那么就要在onDestory中確定它是否結束了,如果沒有,就結束它。


3、onStart和onRestart、onStop

Activity進入到Stopped狀態之后,它極有可能被系統所回收,在某些極端情況下,系統可能是直接殺死應用程序的進程,而不是調用onDestory方法,所以我們需要在onStop方法中盡可能的釋放那些用戶暫時不需要使用的資源,防止內存泄露。

盡管onPause在onStop之前執行,但是onPause只適合做一些輕量級的操作,更多的耗時耗資源的操作還是要放在onStop里面,比如說對數據保存,需要用到的數據庫操作。


因為從Stopped狀態重啟之后, onStart和onRestart方法都會被執行,所以我們要判斷哪些操作分別要放在哪個方法里面 。因為可能在onStop方法里面釋放了一些資源,那么我們必須要重啟他們,這個時候這些重啟的操作放在onStart方法里面就比較好(因為onCreate之后也需要開啟這些資源)。那些因為Stopped之后引發的需要單獨操作的代碼,就可以放在onRestart里面。


4、onResume和onPause

onPause和onResume中做的操作,其實意義上和onStart和inStop差不多,只不過是要更輕量級的,因為onPause不能阻塞轉變到下一個Activity。

比如:停止動畫、取消broadcast receivers。當然相應的需要在onResume中重啟或初始化等等。

有時候也需要在onPause判斷用戶是調用finish結束這個Activity,還是暫時離開,以便區分處理。這時候可以調用isFinishing()方法來判斷。如果是用戶finish這個Activity,那么返回為true,如果只是暫時離開或者被系統回收的話,就返回false。


3.如何強制性關閉一個activity


Android下結束進程的方法  
一、結束一個活動Activity
  要主動的結束一個活動Activity,使用finish方法,而且這個方法最后會調用Activity的生命周期函數onDestroy方法,結束當前的Activity,從任務棧中彈出當前的Activity,激活下一個Activity。
二、強制結束當前的進程
  強行結束當前進程有兩個方法。
  1、killProcess(int pid)              例子:android.os.Process.killProcess(android.os.Process.myPid());
這個方法使用是有條件的:
a、將被殺掉的進程 和 當前進程 處於同一個包或者應用程序中;android:process
b、將被殺掉的進程 是由當前應用程序所創建的附加進程;
c、將被殺掉的進程 和 當前進程 共享了普通用戶的UID。(這里的普通用戶,是相對於Root權限的用戶來說的)android:shareuserid
  2、System.exit(int code)             例子:System.exit(0);
  該方法只能用於結束當前進程自身,在程序遇到異常,無法正常執行時,可以通過這個方法強制退出。 需要把異常捕獲到
  需要注意的是,這兩個方法,會導致進程非正常退出,就是說,進程退出時不會去執行onPause、onStop和onDestroy方法,那么進程很有可能錯過了保存數據的機會。因此,這兩個方法最好使用在出現異常的時候!
三、結束另一個進程
  要通過一個進程去結束另一個進程。在之前的SDK版本中,一直使用方法restartPackage(packageName)方法,但是在Android的開發文檔中介紹說,這個函數會導致一些問題( the previous behavior here is no longer available to applications because it allows them to break other applications by removing their alarms, stopping their services, etc.),所以建議大家使用一個新的方法: 
  void killBackgroundProcesses(String packageName)
  由於這個方法沒有返回值,所以我們也不知道我們的目標進程是否真的退出了。但是,我目前只發現了這個可以結束另一個進程的方法。
四、退出到主屏幕
  這個方法,也是退出當前進程的一個方法。如果我們在進程中創建了很多的Activity,但是又不想關閉時去退出不在任務棧頂的Activity,那么就可以直接使用這個方法了。


mHomeIntent = new Intent(Intent.ACTION_MAIN, null);
mHomeIntent.addCategory(Intent.CATEGORY_HOME);
mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);


4.activity的模板方法模式,請看前面的文章



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com