Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Activity基礎篇整理

Activity基礎篇整理

編輯:關於Android編程

一,Activity生命周期

\ 相信不少朋友也已經看過這個流程圖了,也基本了解了Activity生命周期的幾個過程,我們就來說一說一些常見操作的生命周期執行情況吧 (1) 啟動Activity:onCreate()->onStart()->onResume->Activity進入運行狀態 (2) 被其他Activity,窗口覆蓋或鎖屏:onPause()->暫停當前Activity狀態 (3)當前Activity由被覆蓋狀態回到前台或解鎖屏:onResume()->再次進入運行狀態 (4)當前Activity轉到新的Activity界面或按Home鍵回到主屏,自身退居後台:onPause()->onStop->不可見狀態 (5) 回退到不可見狀態的Activity:onRestart()->onStart()->onResume->再次進入運行狀態 (6)當前Activity處於被覆蓋狀態或者後台不可見狀態,即第2步和第4步,系統內存不足,殺死當前Activity,而後用戶退回當前Activity:onCreate()->onStart()->onResume()->進入運行狀態 (7)用戶finish退出當前Activity:onPause()->onStop()->onDestory()->結束當前Activity   擴展一些:   1 . onWindowFocusChanged:在Activity窗口獲得或失去焦點時被調用,在onResume與onPause後調用 onResume()->onWindowFocusChanged()->運行狀態->onPause->onWindowFocusChanged() 比如onCreate中Window對象沒有初始化完成,一些動態計算控件大小,動畫加載可能報錯,所以可以將加載相關的代碼放在這個方法中執行   2 .onSaveInstanceState與 onRestoreInstanceState: (1)在Activity被覆蓋或退居後台之後,系統資源不足將其殺死,onSaveInstanceState會被調用,回退到此Activity時,調用onRestoreInstanceState (2)在用戶改變屏幕方向時,系統先銷毀當前的Activity,然後再重建一個新的,調用此方法保存一些臨時數據; (3)在當前Activity跳轉到其他Activity或者按Home鍵回到主屏,自身退居後台時,此方法會被調用。系統調用此方法是為了保存當前窗口各個View組件的狀態.   保存狀態時調用順序:運行狀態->onSaveInstanceState()->onPause() 恢復狀態時調用順序:onStart()->onRestoreInstanceState()->onResume   3.onConfigurationChange():當指定了android:configChanges="orientation"後,方向改變時onConfigurationChanged被調用,可以setContentView(R.layout.orientation_landscape),設置Activity不同的xml布局文件適配  

二.Fragment 碎片

1.產生與介紹   為了讓界面可以在平板上更好地展示,Android在3.0版本引入了Fragment(碎片)功能,它非常類似於Activity,可以像Activity一樣包含布局。Fragment通常是嵌套在Activity中使用的,可以把Fragment當成Activity的一個界面的一個組成部分,Fragment擁有自己的生命周期和接收、處理用戶的事件,這樣就不必在Activity寫一堆控件的事件處理的代碼了。更為重要的是,你可以動態的添加、替換和移除某個Fragment.碎片化管理屏幕顯示的思路 比如,一個應用,其中2個頁面,listview列表顯示所有內容項FragmentA,對應詳情頁FragmentB,在豎屏時只嵌入FragmentA,橫屏時,嵌入FragmentA與FragmentB,並列左邊列表,右邊詳情. 以及ViewPager+Fragment導航欄組合的應用主頁等   2.生命周期 \ 對比Activity的生命周期,可見Activity的回掉方法碎片中幾乎都有,碎片還提供了一些附加方法
  • onAttach() 當碎片和活動建立關聯的時候調用,add後, 在這個方法中可以獲得所在的activity,
  • onCreateView()為碎片創建視圖(加載布局)時調用
  • onActivityCreated()確保與碎片相關聯的活動一定已經創建完畢的時候調用
  • onDestroyView()當與碎片關聯的視圖被移除的時候調用
  • onDetach()當碎片和活動解除關聯的時候調用
  (1).第一次加載屏幕:onAttach() -- onCreate()--- onCreateView()--onActivityCreated()--onStart()--onResume() (2)點擊替換:onPause()--onStop()---onDestoryView() (如果替換的時候沒有調用addToBackStack()方法,此時onDestory()--onDetach()方法也會得到執行) (3)當點擊Back重新回到這個Frament界面:onCreateView()--onStart()--onResume() (onCreate()和onAttach()並沒有執行,所以我們使用的addToBackStacck()方法使得Fragment沒有銷毀,與Activity解綁) (4)按下back時響應:onPause()--onStop()---onDestoryView()--onDestory()--onDetach()     動態添加碎片 主要有以下五個步驟:
  • 創建待添加碎片實例
  • 獲取到FragmentManager,在活動中可以直接調用getFragmentManager()方法得到
  • 開啟一個事務,FragmentTransaction transaction = fm.benginTransatcion();通過調用beginTransaction()方法開啟,保證Fragment操作的原子性
  • 向容器內加入碎片,一般使用transaction.replace()方法實現,就是remove和add合體,需要傳入容器的ID和待添加的碎片實例transaction.add(),remove(),hide(),show(),detach(),attach()
  • 提交事物,調用commit()方法來完成

實用情景 a、比如:我在FragmentA中的EditText填了一些數據,當切換到FragmentB時,如果希望會到A還能看到數據,則適合你的就是hide和show;也就是說,希望保留用戶操作的面板,你可以使用hide和show,當然了不要使勁在那new實例,進行下非null判斷。

b、再比如:我不希望保留用戶操作,你可以使用remove(),然後add();或者使用replace()這個和remove,add是相同的效果。

c、remove和detach有一點細微的區別,在不考慮回退棧的情況下,remove會銷毀整個Fragment實例,而detach則只是銷毀其視圖結構,實例並不會被銷毀。那麼二者怎麼取捨使用呢?如果你的當前Activity一直存在,那麼在不希望保留用戶操作的時候,你可以優先使用detach   Fragment與Activity通信

因為所有的Fragment都是依附於Activity的,所以通信起來並不復雜,大概歸納為:

a、如果你Activity中包含自己管理的Fragment的引用,可以通過引用直接訪問所有的Fragment的public方法

b、如果Activity中未保存任何Fragment的引用,那麼沒關系,每個Fragment都有一個唯一的TAG或者ID,可以通過getFragmentManager.findFragmentByTag()或者findFragmentById()獲得任何Fragment實例,然後進行操作。

c、在Fragment中可以通過getActivity得到當前綁定的Activity的實例,然後進行操作。   使用DialogFragment來管理對話框,當旋轉屏幕和按下後退鍵時可以更好的管理其聲明周期,它和Fragment有著基本一致的聲明周期。且DialogFragment也允許開發者把Dialog作為內嵌的組件進行重用,類似Fragment(可以在大屏幕和小屏幕顯示出不同的效果)  

三.Activity的加載模式解析

  1.Activity stack 每個Activity的狀態是由它在Activity棧中的位置決定的。 Activity棧是一個後進先出LIFO,包含所有正在運行Activity的隊列

當一個新的Activity啟動時,當前的活動的Activity將會移到Activity棧的頂部。

如果用戶使用後退按鈕返回的話,或者前台的Activity結束,在棧上的Activity將會移上來並變為活動狀態 一個應用程序的優先級是受最高優先級的Activity影響的。當決定某個應用程序是否要終結去釋放資源,Android內存管理使用棧來決定基於Activity的應用程序的優先級。

2.Activity狀態
一般認為Activity有以下四種狀態:

活動的:當一個Activity在棧頂,它是可視的、有焦點、可接受用戶輸入的。Android試圖盡最大可能保持它活動狀態,殺死其它Activity來確保當前活動Activity有足夠的資源可使用。當另外一個Activity被激活,這個將會被暫停。
暫停:在很多情況下,你的Activity可視但是它沒有焦點,換句話說它被暫停了。有可能原因是一個透明或者非全屏的Activity被激活。
當被暫停,一個Activity仍會當成活動狀態,只不過是不可以接受用戶輸入。在極特殊的情況下,Android將會殺死一個暫停的Activity來為活動的Activity提供充足的資源。當一個Activity變為完全隱藏,它將會變成停止。
停止:當一個Activity不是可視的,它“停止”了。這個Activity將仍然在內存中保存它所有的狀態和會員信息。盡管如此,當其它地方需要內存時,它將是最有可能被釋放資源的。當一個Activity停止後,一個很重要的步驟是要保存數據和當前UI狀態。一旦一個Activity退出或關閉了,它將變為待用狀態。 待用: 在一個Activity被殺死後和被裝在前,它是待用狀態的。待用Acitivity被移除Activity棧,並且需要在顯示和可用之前重新啟動它。   3.四種加載模式   Activity中特性launchMode的四種加載模式解析: 標准,單頂(棧頂復用),單棧(單棧共享),單例(多棧共享)。
  • standard: 標准模式,一調用startActivity()方法就會產生一個新的實例。
  • singleTop: 如果已經有一個實例位於Activity棧的頂部時,就不產生新的實例,而只是調用Activity中的newInstance()方法。如果不位於棧頂,會產生一個新的實例,。
  • singleTask: 會在一個新task的棧中產生這個實例,以後每次調用都會使用這個,不會去產生新的實例了,並且處於棧低,加入其它Activity,返回自動彈出銷毀。
  • singleInstance: 這個跟singleTask基本上是一樣,會在一個新task的棧中產生這個實例.只有一個區別:在這個模式下的Activity實例所處的task中,只能有這個activity實例,不能有其他的實例, 是其所在棧的唯一activity,整個系統單例,任何task中調用,它會每次都被重用,多棧共用,2個應用調用顯示同一個Activity,第一個中退出,只是把這個棧移開了,第二個退出時,這個activity棧才會退出。   在Android平台上可以將task簡單的理解為由多個Activity共同協作完成某項應用任務,而不管Activity具體屬於哪個Application,每一個Task有自己對應的 Activity Stack.  
Activity的加載模式受啟動Activity的Intent對象中設置的Flag和manifest文件中Activity的元素的特性值交互控制。

下面是影響加載模式的一些特性

核心的Intent Flag有:
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
FLAG_ACTIVITY_SINGLE_TOP
核心的特性有:
taskAffinity
launchMode
allowTaskReparenting
clearTaskOnLaunch
alwaysRetainTaskState finishOnTaskLaunc   加載模式便是決定以哪種方式啟動一個跳轉到某個Activity實例,各種加載模式區別在於下面幾點: (1)所屬task的區別 一般情況下,“standard”和”singleTop”的activity的目標task,和收到的Intent的發送者在同一個task內,就相當於誰調用它,它就跟誰在同一個Task中。 除非Intent包括參數FLAG_ACTIVITY_NEW_TASK。設置FLAG_ACTIVITY_NEW_TASK參數,會啟動到別的task裡。 “singleTask”和”singleInstance” 總是把要啟動的activity作為一個task的根元素,他們會被啟動到一個其他task裡。 (2)是否允許多個實例 “standard”和”singleTop”可以被實例化多次,並且是可以存在於不同的task中;這種實例化時一個task可以包括一個activity的多個實例;
“singleTask”和”singleInstance”則限制只生成一個實例,並且是task的根元素。 singleTop 要求如果創建intent的時候棧頂已經有要創建的Activity的實例,則將intent發送給該實例,而不創建新的實例。 (3)是否允許其它activity存在於本task內 “singleInstance”獨占一個task,其它activity不能存在那個task裡; 即便此Activity又啟動了一個新的activity,不管新的activity的launch mode 如何,新的activity都將會到別的task裡運行(如同加了FLAG_ACTIVITY_NEW_TASK參數)。而另外三種模式,則可以和其它activity共存。 (4)是否每次都生成新實例 “standard”對於每一個啟動Intent都會生成一個activity的新實例; “singleTop”的activity如果在task的棧頂的話,則不生成新的該activity的實例,直接使用棧頂的實例,否則,生成該activity的實例。 “singleInstance”是其所在棧的唯一activity,所有task共享,它會每次都被重用。 “singleTask” 如果不存在,則在新task中生成實例,存在即復用,彈出該task棧中其他activity   。


四.Activity與Window,View的關系解析

  Android系統中的所有UI類都是建立在View和ViewGroup這兩個類的基礎上的。所有View的子類成為”Widget”,所有ViewGroup的子類成為”Layout”。View和ViewGroup之間采用了組合設計模式,可以使得“部分-整體”同等對待。ViewGroup作為布局容器類的最上層,布局容器裡面又可以有View和ViewGroup。LayoutInfalter就是用來生成View的一個工具,XML布局文件就是用來生成View的原料 LayoutInflater是一個用來實例化XML布局文件為View對象的類 LayoutInflater.infalte(R.layout.test,null)用來從指定的XML資源中填充一個新的View   Activity構造的時候只能初始化一個Window(PhoneWindow),另外這個PhoneWindow有一個”DecorView”,是主窗口中頂級view,這個”DecorView”是一個ViewGroup,是最初始的根視圖,之後不斷重疊ad view,removeview管理,放到window顯示窗, 還可以onCreater中設置窗口,顯示屬性,比如設置無標題,全屏等。   getWindow().setContentView(LayoutInflater.from(this).inflate(R.layout.main, null)),  

public void setContentView(View view,ViewGroup.LayoutParams params) {

if (mContentParent == null) {

installDecor();

} else {

mContentParent.removeAllViews();

}

mContentParent.addView(view, params);

final Callback cb = getCallback();

if (cb != null) {

cb.onContentChanged();//窗口類容發生變化時更新

}

}          
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved