Android in Practice筆記第三章

第三章

<!--[if !supportLists]-->1.       <!--[endif]-->Application生命週期

每個Android的應用都有一個Application對象,我們可以使用該對象共享一些狀態,即使我們不繼承Application,提供自己的Application對象,Android平臺也爲我們提供一個默認的Application對象。

生命週期爲:

<!--[if !supportLists]-->1)      <!--[endif]-->onCreate在應用程序開始的時候被調用。該方法一定要實現的快。

<!--[if !supportLists]-->2)      <!--[endif]-->onLowMemory在系統需要回收應用時調用。可以在這裏清除緩存或者其他釋放內存的操作,這樣做的好處是如果你釋放了足夠多的內存,系統不會停止該應用。

<!--[if !supportLists]-->3)      <!--[endif]-->onTerminate在應用被停止時,偶爾被調用

<!--[if !supportLists]-->4)      <!--[endif]-->onConfigurationChanged當應用程序運行時設備配置發生變化時調用

Constant

Value

Description

mcc

0x0001

The IMSI MCC has changed, that is a SIM has been detected and updated the Mobile Country Code.

mnc

0x0002

The IMSI MNC has changed, that is a SIM has been detected and updated the Mobile Network Code.

locale

0x0004

The locale has changed, that is the user has selected a new language that text should be displayed in.

touchscreen

0x0008

The touchscreen has changed. Should never normally happen.

keyboard

0x0010

The keyboard type has changed, for example the user has plugged in an external keyboard.

keyboardHidden

0x0020

The keyboard or navigation accessibility has changed, for example the user has slid the keyboard out to expose it. Note that despite its name, this applied to any accessibility: keyboard or navigation.

navigation

0x0040

The navigation type has changed. Should never normally happen.

orientation

0x0080

The screen orientation has changed, that is the user has rotated the device.

screenLayout

0x0100

The screen layout has changed. This might be caused by a different display being activated.

uiMode

0x0200

The global user interface mode has changed. For example, going in or out of car mode, night mode changing, etc.

screenSize

0x0400

The current available screen size has changed. If applications don't target at least HONEYCOMB_MR2 then the activity will always handle this itself (the change will not result in a restart). This represents a change in the currently available size, so will change when the user switches between landscape and portrait.

smallestScreenSize

0x0800

The physical screen size has changed. If applications don't target at least HONEYCOMB_MR2 then the activity will always handle this itself (the change will not result in a restart). This represents a change in size regardless of orientation, so will only change when the actual physical screen size has changed such as switching to an external display.

fontScale

0x40000000

The font scaling factor has changed, that is the user has selected a new global font size.

 

<!--[if !supportLists]-->2.       <!--[endif]-->用戶啓動一個Android應用的時候,會使用一個唯一的用戶ID去啓動一個新的進程,這樣就能讓每個應用程序有獨立的內存和狀態,以及安全和多任務。

每個進程都有一個主線程(Main Thread),這個主線程一般被稱爲UI Thread

<!--[if !supportLists]-->3.       <!--[endif]-->Choose which processes get the ax

Android平臺會儘可能的保證應用的進程存在,但是因爲資源有限,系統會關閉一些進程。Android平臺通過5個級別去找到哪個進程可以被關閉:

<!--[if !supportLists]-->1)      <!--[endif]-->Foreground:用戶正在交互的

<!--[if !supportLists]-->2)      <!--[endif]-->Visible:這個不太明白

<!--[if !supportLists]-->3)      <!--[endif]-->Service:通過startService啓動的Service

<!--[if !supportLists]-->4)      <!--[endif]-->Background:後臺運行的Activity的進程。當有多個進程時,使用LRU

<!--[if !supportLists]-->5)      <!--[endif]-->Empty:沒有和任何應用程序組件掛鉤的進程

<!--[if !supportLists]-->4.       <!--[endif]-->通過設置android:process的屬性,可以讓一個應用跑在多個進程裏或者多個應用跑在一個進程裏。默認是每個應用一個進程,當多個應用爲了更輕鬆的訪問同一個文件時,可以讓多個應用跑在一個進程裏。但是多個應用跑在同一個進程裏時,會增加快垃圾收集的次數,會影響應用的運行速度。

<!--[if !supportLists]-->5.       <!--[endif]-->Activity的生命週期

<!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter" /> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0" /> <v:f eqn="sum @0 1 0" /> <v:f eqn="sum 0 0 @1" /> <v:f eqn="prod @2 1 2" /> <v:f eqn="prod @3 21600 pixelWidth" /> <v:f eqn="prod @3 21600 pixelHeight" /> <v:f eqn="sum @0 0 1" /> <v:f eqn="prod @6 1 2" /> <v:f eqn="prod @7 21600 pixelWidth" /> <v:f eqn="sum @8 21600 0" /> <v:f eqn="prod @7 21600 pixelHeight" /> <v:f eqn="sum @10 21600 0" /> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect" /> <o:lock v:ext="edit" aspectratio="t" /> </v:shapetype><v:shape id="Picture_x0020_1" o:spid="_x0000_i1025" type="#_x0000_t75" alt="Activity生命週期記憶" style='width:442.5pt;height:221.25pt;visibility:visible; mso-wrap-style:square'> <v:imagedata src="file:///C:\Users\hehai\AppData\Local\Temp\msohtmlclip1\01\clip_image001.png" o:title="Activity生命週期記憶" /> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->

不難看出,其實這些方法都是兩兩對應的,onCreate創建與onDestroy銷燬;onStart可見與onStop不可見;onResume可編輯(即焦點)與onPause;這6個方法是相對應的,那麼就只剩下一個onRestart方法了,這個方法在什麼時候調用呢?答案就是:在ActivityonStop後,但是沒有被onDestroy,在再次啓動此Activity時就調用onRestart(而不再調用onCreate)方法;如果被onDestroy了,則是調用onCreate方法。

這樣大家就應該能夠很容易的記住這些方法了。下面再通過一個比喻來看兩個Activity的切換過程。

我們把Activity比作一本書,我們要看書,首先從書架上取出書(onCreate),然後放到桌上(onStart),接着打開書(onResume),這樣我們就可以看書並可以在書本上寫字了。

如果這時候我們要啓動另一個Activity,也就是要看另一本書,首先我們放下手中的筆或者說合上書(onPause),然後從書架上拿下另一本書(書2onCreate),然後把書本2放到桌上並打開(書2onStartonResume)。

如果書本1被書本2完全蓋住了,即不可見了,就調用書本1onStop;而如果書本2較小,沒有完全蓋住書本1,則不會調用。

我們還可以把書本1放回書架上,即onDestroy

另外,還有一點要注意,Activity在處於onPauseonStoponDestroy狀態下,系統都可以銷燬該Activity所在進程,所以我們在處理一些要保存的數據時,必須在onPause方法中進行,因爲onStoponDestroy方法不一定會被調用。

<!--[if !supportLists]-->1)      <!--[endif]-->onCreateActivity第一次被創建時調用該方法。應該在這個方法裏做所有的靜態初始化:創建viewslist綁定數據等。該方法還提供包含了上次的狀態的Bundle的參數,可以通過這個參數恢復ActivityAlways followed by  onStart.

<!--[if !supportLists]-->2)      <!--[endif]-->onRestart: Activitystop之後,沒有被destory,但是又被用戶調用時調用這個方法。Always followed by onStart.

<!--[if !supportLists]-->3)      <!--[endif]-->onStart: Activity變成可見時調用該方法。Followed by onResume if the activity comes to the foreground, or onStop if it becomes hidden.

<!--[if !supportLists]-->4)      <!--[endif]-->onResume: Activity開始跟用戶交互的時候調用該方法。這時,這個Activityactivity棧的最上面。Always followed by onPause.    覆蓋該方法去更新Activity的視圖,是更新而不是重新創建。可以通過web service取數據然後刷新views

<!--[if !supportLists]-->5)      <!--[endif]-->onPause: 當系統開始恢復前一個activity的時候調用。在這個方法裏一般用來提交未保存的改變到數據庫,停止動畫以及其他消耗CPU的事情。因爲在這個方法未結束之前,要恢復的activity不會調用onResume方法,所以這個方法推薦很快就返回。Followed by either onResume if the activity returns to the front, or onStop if it becomes invisible to the user.  一般請覆蓋該方法,在該方法裏清楚Activity創建的東西,以回收內存。

<!--[if !supportLists]-->6)      <!--[endif]-->onStop: Activity因爲其他Activity調用了onResume的方法而覆蓋了本Activity不再被可見時調用。當一個新的Activity開始了或者已經存在的Activity被拿到前面時,或者當前這個Activitydestoryed時。Followed by either onRestart if this activity is coming back to interact with the user, or onDestory if this activity is going away.

<!--[if !supportLists]-->7)      <!--[endif]-->onDestory: 當該Activity結束時或者系統爲了節約內存零時destoryactivity時會調用該方法。可以使用isFinishing方法來判斷是上面的那一種情況。如果是因爲回收內存而被destory,緊接着的是onRestart方法。

<!--[if !supportLists]-->6.       <!--[endif]-->Configuration

Configuration類定義了設備的所有配置信息。包括硬件配置,設備方向,屏幕大小,語言設置等等。

Configuration改變的時候,Androiddestoryrecreate當前的Activity

Configuration改變時,Android會調用onPauseonDestorydestory當前的Activity,然後調用當前的ActivityonCreateonResume方法重建當前的Activity。同時,instance state也通過onSaveInstanceStatonRestoreInstanceState這兩個方法保存和恢復。

通過設置android:configChange的值,可以讓Android不銷燬和重建Activity

<!--[if !supportLists]-->7.       <!--[endif]-->Activity的實例狀態(instance state

Instance state:沒有提交的form表單,selectionsListviewindex等數據,與Activity的生命週期一樣。

Persistent state

 

Instance stateAndroid系統destory一個Activity時會保存(Configuration改變或者別的)。在Activityfinish(按Back按鈕)之後不會被保存。

 

ActivityonRestoreInstanceState(Bundle savedInstanceState)方法和onSaveInstanceState(Bundle outstate) 方法來恢復和保存Activity的實例狀態(instance state

<!--[if !supportLists]-->8.       <!--[endif]-->Noconfiguration instance state

Noconfiguration instance state就是在Activity兩個實例之間傳遞的state,因爲Activity會被destory,然後重建Activity之後可以通過Noconfiguration instance state得到上一個實例的一些狀態。

使用getLastNonConfigurationInstance方法取得上一個實例的noconfiguration instance state

使用onRetainNonConfigurationInstance方法返回你想傳遞的內容

需要注意的事情是實例之間傳遞的狀態可以是任意對象,但是不要有當前Activity的引用,否則這樣會導致Activity不能被回收,造成內存泄露。

不要隨意使用

不要傳遞會跟configuration變化而變化的資源

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章