Android進階#(1/12)Android的構成基石——四大組件_Activity

####反正現在的 感情 都 曖昧,你大可不必爲難找般配。####

####雖然Kotlin的重構之風已起,但即便30年前的彙編也是有嚼頭的####

聲明:本內容爲何紅輝所著《Android開發進階——從小工到專家》一書讀書筆記來的。

內容有三個部分:

一、Android開發核心:View與動畫、多線程、網絡、數據庫、性能優化,深入瞭解開發中最爲重要的知識;

二、代碼規範、單元測試、版本控制、OOP與模式、重構等,使讀者具備構建低耦合、靈活性強的應用軟件; 

三、一個完整的示例,演示如何把一個充滿問題的應用軟件逐步演化爲 低耦合、清晰、可測試的實現過程。其中展示了常見的重構方法、測試手段,從真實的示例中汲取知識和經驗,提升技術與設計能力,繞過編程中的諸多陷阱。

另注:

本書示例代碼都託管在GitHub,地址:https://github.com/bboyfeiyu/android_jtm_sourcecode,讀者可通過Git進行下載。

#### 如果是單純的版面網頁文檔化,逐一目錄內容的去摘錄,就顯得贅餘了。####


(1/12)Android的構成基石——四大組件

 |  Activity  |  Service  |  ContentProvider  |  Broadcast  |

這4個組件分工明確,共同構成了 可重用、靈活、低耦合的Android系統。

Activity負責 UI元素的加載與頁面之間的跳轉,代表了一個頁面單元。

Service負責 與UI無關的工作,如在後臺執行耗時操作等。

ContentProvider負責 存儲、共享數據,使得數據可以在多個應用之間共享。

Broadcast則是在各個組件、應用之間進行通信,簡化了Android開發中通信問題。

Activity

Activity在應用中的表現就是一個用戶界面。它會加載指定的佈局文件來顯示各種UI元素,例如:TextView,Button,ImageView,ListView等,並且爲這些UI元素設置事件處理函數,使得用戶可以與這些UI進行交互。同時,Activity還可以在不同的Activity之間跳轉,將不同的頁面串連在一起,共同完成特定的操作流程。每個應用都是由一個或多個Activity組成,它是Android應用程序中不可缺少的部分。

啓動應用時會加載一個默認的Activity,這個Activity在AndroidManifest.xml中會被設置爲如下intent-filter:



每個Activity都有生命週期,在不同的階段回調不同生命週期函數,Activity的生命週期函數有如下幾個:

1.onCreate()

相信這是開發者見過的次數最多的函數,我們在創建繼承者自Activity的類時都會默認生成這個函數。

它會在Activity第一次被創建時調用,通常會在這個函數中完成Activity的初始化操作,如設置佈局、初始化視圖、綁定事件等。

2.onStart()

這個函數在Activity的onCreate函數調用之後被調用,此時的Activity還處在不可見狀態,它的下一個狀態就是Activity變得可見的時候。也就是這個函數在Activity可見之前被調用。

3.onResume()

這個函數在Activity變爲可見時被調用,執行完onResume之後,Activity就會請求AMS渲染它所管理的視圖。

此時的Activity一定位於返回棧的棧頂,並且處於運行狀態。

4.onPause()

這個函數在系統準備去啓動或者恢復另一個Activity時調用,也就是在Activity即將從可見狀態變爲不可見時,我們通常會在這個函數中將一些消耗CPU的資源釋放掉,以及保存一些關鍵數據。

5.onStop()

這個函數在Activity完全不可見時調用,它和onPause()函數的主要區別是,如果新啓動的Activity是一個對話框式的Activity,那麼onPause()函數會得到執行,而onStop()函數並不會執行。

6.onDestroy()

這個函數在Activity被銷燬之前調用,之後Activity的狀態將變爲銷燬狀態。

7.onRestart()

這個函數在Activity由停止狀態重新變爲運行狀態之前調用,也就是Activity被重新啓動了。


從onCreate()函數到onDestroy()函數運行的時期就是一個完整的Activity生命週期。

一般情況下,我們會在一個Activity的onCreate()函數中完成各種初始化操作;

而在onDestroy()函數中完成釋放內存的操作。

然而並不是各個時期Activity都是可見的 ,只有 onResume()函數和 onStop()函數之間的Activity是可見的,在Activity可見期內,用戶可以與Activity進行交互,完成所需的功能。


Activity 的構成

Activity的構成並不是一個Activity對象再加上一個佈局文件那麼簡單哦。

在Activity和開發人員設置的視圖之間還隔着兩層。

實際上視圖會被設置給一個Window類,這個Window中含有一個DecorView,這個DecorView纔是整個窗口的頂級視圖。

開發人員設置的佈局會被設置到這個DecorView 的 mContentParent 佈局中。

也就是所Android中實際上內置了一些系統佈局文件xml,我們在xml中定義的視圖最終被設置到這些系統佈局的特定節點之下,這樣就形成了整個DecorView。

【這是簡易結構圖】


下面是一個名爲screen_title 的系統佈局xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:fitsSystemWindow="true">
    <!-- Popout bar for action modes -->
    <ViewStub android:id="@+id/action_mode_bar_stub"
                android:inflatedId="@+id/action_mode_bar"
                android:layout="@layout/action_mode_bar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:theme="?attr/actionBarTheme"/>
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="?android:attr/windowTitleSize"
        style="?android:attr/windowTitleBackgroundStyle">
        <TextView android:id="@android:id/title"
            style="?android:attr/windowTitleStyle"
            android:background="@null"
            android:fadingEdge="horizontal"
            android:gravity="center_vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </FrameLayout>
    <!-這裏就是開發人員設置的佈局所填充的位置-->
    <FrameLayout android:id="@android:id/content"
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:foregroundGravity="fill_horizontal|top"
        android:foreground="?android:attr/windowContentOverlay"></FrameLayout>
</LinearLayout>

文件總包含了actionbar和標題欄區域,下面就是開發人員設置給Activity的佈局區域,這個區域被添加到名爲content 的佈局中,而這整個screen_title.xml又是DecorView的子視圖,因此,最終用戶界面會顯示爲標題欄、開發人員設置的界面。

Activity的4種啓動模式

每個應用程序都是由一個或者多個Activity組成。

因此,Android內部使用通過回退棧來管理Activity實例。

棧是一種後進先出的集合。

對於Android來說,當期顯示的Activity就在棧頂,當用戶點擊後退鍵或者點擊應用上的返回按鈕,系統就會將棧頂的Activity出棧。

此時,原來棧頂下的Activity就會變爲棧頂顯示到設備上。


然而,事情可能並不是那麼簡單,在一些特殊情況下我們可能需要對Activity實例做一些特殊的處理,

例如,爲避免重複創建Activity,我們要求一個Activity只有一個實例。

好在Android系統爲我們提供了這些功能,也就是我們本節要說的Activity的4 個啓動模式。

用戶可以在AndroidMainfext.xml註冊Activity時設置它的啓動模式。

例如:

<activity 
            android:name=".MyActivity"
            android:launchMode="singleTask"
            android:label="@string/app_name">
        </activity>
Activity啓動模式有四個:


singleTask

singleInstance

singleTop

standard

蝦米卓哥介紹:

1)standard(標準啓動)

其實就是默認的啓動模式。

這種模式下啓動的Activity可以被多次實例化,即在同一個任務棧中可以存在多個Activity實例。每個實例都會處理一個Intent對象。如果Activity A的啓動模式爲standard,並已有一個Activity A被啓動,在該Activity A中調用startActivity 時會啓動一個新的 Activity A實例。

棧的變化如下:


如果Activity A是一個非常耗資源的類。那麼將會使它所依附的應用消耗更多的系統資源。

2)singleTop(如果此Activity實例已在棧頂)

如果一個以singleTop模式啓動Activity的實例已經存在於任務棧的棧頂。那麼再啓動這個Activity時,不會創建新的實例,而是重用位於棧頂的那個實例,並且會調用該實例的onNewIntent()函數將Intent對象傳遞到這個實例中。

例如:Activity的啓動模式爲singleTop,並且Activity A的一個實例已經存在於棧頂中。那麼再調用startActivity啓動另一個Activity A 時,不會再次創建 Activity A的實例,而是重用原來的實例,並且調用原來實例 的 onNewIntent()函數。此時任務棧中還是這一個Activity A 的實例。


如果以singleTop模式啓動的Activity的一個實例已經存在於任務棧中,但是不在棧頂,那麼它的行爲和standard模式相同也會創建一個新的實例。


3)singleTask(常用啓動模式)

singleTask 模式是常用的啓動模式,如果一個Activity 設置了該啓動模式,那麼在一個任務棧中只能有一個該 Activity的實例。

如果任務棧中還沒有改Activity,會新創建一個實例並放在棧頂。但是,如果已經存在 Activity ,系統會銷燬處在該 Activity 實例處於棧頂,同時回調該Activity的onNewIntent()方法。

棧內變化如圖:

4)singleInstance

設置了singleInstance模式的Activity會在一個獨立的任務中開啓,並且這個新的任務中有且只有這一個實例。

即就是說,被該實例啓動的其它Activity會自動運行於另一個任務中。

當再次啓動該Activity實例時,會重用已存在的任務和實例,並調用該實例的onNewIntent()函數,將Intent實例傳遞到該實例。


就是說,singleInstance能夠保證Activity在系統中只有一個實例,不管多少應用要啓動該Activity,這個Activity有且只有一個。而不是在不同的任務棧中可以同時存在同一個Activity(比如singleTask啓動的Activity)。

FragmentActivity與Fragment

爲了更好地運用越來越大屏幕空間,Android在3.0版本引入了Fragment,它可以像Activity一樣包含佈局。

不同的是Fragment是被嵌套在Activity中使用,它作爲一個更大粒度的UI單元。如果需要兼容低於Android3.0的系統,那麼開發人員需要引用android-support-v4 的jar包才能使用Fragment功能。

假如這樣的場景:

wo們的新聞應用含有兩個Activity,第一個Activity是顯示新聞標題、概要信息的列表,當用戶點擊這些標題時進入該新聞的詳細頁面進行閱讀。

Fragment爲了應對這種情況出現,我們可以使用兩個Fragment。


每個Activity包含一個Fragment


橫屏模式下包含兩個Fragment的Activity


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