1. 程式人生 > >Android Activity介紹

Android Activity介紹

Activity生命週期

這裡寫圖片描述

狀態說明

狀態 說明
活動狀態 當Activity在使用者介面中處於最上層,完全能被使用者看到,能夠與使用者進行互動,則這個Activity處於活動狀態。
暫停狀態 當Activity在介面上被部分遮擋,該Activity不再處於使用者介面的最上層,且不能與使用者進行互動,則這個Activity處於暫停狀態。
停止狀態 當Activity在介面上完全不能被使用者看到,也就是說這個Activity被其他Activity全部遮擋,則這個Activity處於停止狀態。
非活動狀態 活動狀態、暫停狀態和停止狀態是Activity的主要狀態,不在以上三種狀態下的Activity的則處於非活動狀態。

狀態變換圖

這裡寫圖片描述

  • Activity啟動後處於活動狀態,此時的Activity位於介面的最上層,是與使用者正在進行互動的元件,因此Android系統會努力保證處於活動狀態的Activity的資源需求,資源緊張的時候可以終止其他狀態的Activity;
  • 如果使用者啟動了新的Activity,部分遮擋了當前的Activity,或新的Activity是半透明的,則當前的Activity轉換為暫停狀態,Andorid系統僅為處於活動狀態的Activity釋放資源時才終止處於暫停狀態的Activity
  • 如果使用者啟動新的Activity 完全遮擋了當前的Activity,則當前的Activity轉變為停止狀態,停止狀態的Activity將優先被終止
  • 活動狀態的Activity被使用者關閉後,以及暫停狀態或者停止狀態的Activity被系統終止後,Activity便進入了非活動的狀態。
  • **注意:**一般來說,Andorid系統會優先終止處於停止狀態,且位置靠近棧底的Activity,因為這些Activity被使用者再次呼叫的機會最小,且在介面上使用者是看不到的。

事件回撥事件

這裡寫圖片描述

Activity生命週期的事件回撥函式

函式 是否可終止 說明
onCreate() Activity啟動後第一個被呼叫的函式,常用來進行Activity的初始化,例如建立View、繫結資料或者回覆信息等。
onStart() 當Activity顯示在螢幕上,該函式被呼叫。一般用來初始化與更新介面相關的資源。
onRestart() 當Activity從停止狀態進入活動狀態前,呼叫該函式。
onResume() 當Activity可以接收使用者輸入(獲得焦點)的時候,該函式被呼叫。此時的Activity位於Activity棧的棧頂。
onPause() 當Activity進入暫停狀態的時候,該函式被呼叫。主要用來儲存持久資料,關閉動畫、釋放CPU資源等。該函式中的程式碼必須簡短,因為另一個Activity必須等待該函式執行完畢之後才能顯示在介面上。
onStop() 當Activity不對使用者可見後,該函式被呼叫,Activity進入停止狀態。一般用來暫停或停止與更新介面相關的操作。
onDestory() 在Activity被終止前,即進入非活動狀態前,該函式被呼叫。
有兩種情況該函式會被呼叫:1. 程式主動呼叫finish()函式;2.程式被Android系統終結。

Activity狀態儲存/恢復的事件回撥函式

函式 說明
onSaveInstanceState() 暫停或者停止Acitivity前呼叫該函式,用以儲存Activity的臨時狀態資訊。
onRestoreInstanceState() 恢復onSaveInstanceState()儲存的Activity狀態資訊。

Activity的生命週期的四個不同的階段

Activity的生命週期可劃分為4個不同的階段,且在不同的階段按一定的順序執行相應的事件回撥函式。

  • 啟動Activity
    • 在這個階段依次執行3個事件回撥函式:onCreate → onStart → onResume
  • Activity失去焦點
    • 在這個階段依次執行2個事件回撥函式:onPause → onStop
  • Activity重新獲得焦點
    • 如果Activity重新獲得焦點,會依次執行3個事件回撥函式:onRestart → onStart → onResume
  • 關閉Activity
    • 當Activity被關閉時,會依次執行3個事件回撥函式:onPause → onStop → onDestroy

onPause函式執行過程中改變系統執行軌跡的情況

  • 當Activity失去焦點或被正常關閉時,系統將自動執行onPause函式,其正常執行順序分別為: onPause → onStop → onPause → onStop → onDestroy
  • 如果在執行onPause函式的過程中Activity重新獲得了焦點,然後又失去了焦點,系統將不會按照上述順序在其之後執行onStop函式,而是按照如下順序執行相應的事件回撥函式:onPause → onResume → onPause

onStop函式執行過程中改變系統執行軌跡的情況

  • 當Activity被正常關閉時,系統將自動執行onStop函式,其正常執行順序為: onPause → onStop→ onDestroy
  • 如果在執行onStop函式的過程中Activity重新獲得了焦點,然後又失去了焦點,系統將不會按照上述順序在其之後執行onDestroy函式,而是按照如下順序執行相應的事件回撥函式:onStop → onRestart → onStart → onResume → onPause → onStop

常見的Activity子類

Andorid常見Activity子類使用介紹。

ListActivity

/**
 * @author notzuonotdied
 * @date 18-1-8
 * @describe TODO
 */

public class TestListActivity extends ListActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 建立ListView要用的ArrayList
        List<String> items = fillArray();
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
                android.R.layout.simple_list_item_1, items);
        setListAdapter(adapter);
    }

    private List<String> fillArray() {
        List<String> items = new ArrayList<>();
        items.add("Java");
        items.add("Kotlin");
        items.add("Scala");
        items.add("JVM");
        return items;
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        Toast.makeText(this, getListAdapter().getItem(position).toString(), Toast.LENGTH_SHORT).show();
    }
}

這裡寫圖片描述

PreferenceActivity

標籤註明

標籤 說明
CheckBoxPreference CheckBox選擇項,對應的值的ture或flase。|
EditTextPreference 輸入編輯框,值為String型別,會彈出對話方塊供輸入。
ListPreference 列表選擇,彈出對話方塊供選擇。
Preference 只進行文字顯示,需要與其他進行組合使用。
PreferenceCategory 用於分組。
PreferenceScreen PreferenceActivity的根元素。
RingtonePreference 系統鈴聲選擇。
MultiSelectListPreference 列表選擇(多選)
SwitchPreference Switch

比較老的實現方法

public class TestPreferenceActivity extends PreferenceActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.pref);
    }
}
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory android:title="JVM虛擬機器">
        <CheckBoxPreference
            android:key="java"
            android:title="JAVA" />
        <CheckBoxPreference
            android:key="kotlin"
            android:title="Kotlin" />
        <CheckBoxPreference
            android:key="scala"
            android:title="Scala" />
        <PreferenceScreen android:title="指令碼語言">
            <CheckBoxPreference
                android:key="python"
                android:title="Python" />
            <CheckBoxPreference
                android:key="ruby"
                android:title="Ruby" />
            <ListPreference
                android:dialogTitle="語言列表:"
                android:entries="@array/list"
                android:entryValues="@array/list"
                android:key="list"
                android:summary="有以下幾種"
                android:title="基於JVM虛擬機器的語言" />
            <EditTextPreference
                android:defaultValue="PHP"
                android:dialogTitle="請輸入世界上最好的語言"
                android:key="et"
                android:summary="請輸入內容"
                android:title="請問你需要什麼語言" />
        </PreferenceScreen>
    </PreferenceCategory>

    <PreferenceCategory android:title="@string/app_name">
        <RingtonePreference
            android:key="ring"
            android:summary="選擇音樂"
            android:title="你見過魔法嗎?" />
    </PreferenceCategory>
</PreferenceScreen>

這裡寫圖片描述

新的實現方法

public class TestPreferenceActivity extends PreferenceActivity {
    @Override
    protected boolean isValidFragment(String fragmentName) {
        return true;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 在標題列表中新增一個底部的View
        if (hasHeaders()) {
            Button button = new Button(this);
            button.setText("請點選我");
            setListFooter(button);
        }
    }

    /**
     * 位於Activity最頂部的Header
     */
    @Override
    public void onBuildHeaders(List<Header> target) {
        loadHeadersFromResource(R.xml.preference_headers, target);
    }

    /**
     * 這個是設定選項1的設定內容頁
     */
    public static class Prefs1Fragment extends PreferenceFragment {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            // 從XML中獲取預設值
            PreferenceManager.setDefaultValues(getActivity(),
                    R.xml.advanced_preferences, false);

            addPreferencesFromResource(R.xml.pref);
        }
    }

    /**
     * 這個是設定選項2的設定內容頁
     */
    public static class Prefs2Fragment extends PreferenceFragment {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            // 可以從Header XML中獲取引數
            Log.i("args", "Arguments: " + getArguments());
            
            addPreferencesFromResource(R.xml.pref1);
        }
    }
}

preference_headers.xml

<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">

    <header
        android:fragment="link_work.myapplication.TestPreferenceActivity$Prefs1Fragment"
        android:icon="@mipmap/ic_launcher"
        android:summary="我是副標題,點進去可以看到更多的設定"
        android:title="設定選項1" />

    <header
        android:fragment="link_work.myapplication.TestPreferenceActivity$Prefs2Fragment"
        android:icon="@mipmap/ic_launcher"
        android:summary="我是副標題,點進去可以看到更多的設定"
        android:title="設定選項2">
        <!-- Arbitrary key/value pairs can be included with a header as
             arguments to its fragment. -->
        <extra
            android:name="someKey"
            android:value="someHeaderValue" />
    </header>

    <header
        android:icon="@mipmap/ic_launcher"
        android:summary="啟動一個Intent"
        android:title="Intent">
        <intent
            android:action="android.intent.action.VIEW"
            android:data="http://www.baidu.com" />
    </header>

</preference-headers>

Pref.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory android:title="JVM虛擬機器">
        <CheckBoxPreference
            android:key="java"
            android:title="JAVA" />
        <CheckBoxPreference
            android:key="kotlin"
            android:title="Kotlin" />
        <CheckBoxPreference
            android:key="scala"
            android:title="Scala" />
        <PreferenceScreen android:title="指令碼語言">
            <CheckBoxPreference
                android:key="python"
                android:title="Python" />
            <CheckBoxPreference
                android:key="ruby"
                android:title="Ruby" />
            <ListPreference
                android:dialogTitle="語言列表:"
                android:entries="@array/list"
                android:entryValues="@array/list"
                android:key="list"
                android:summary="有以下幾種"
                android:title="基於JVM虛擬機器的語言" />
            <EditTextPreference
                android:defaultValue="PHP"
                android:dialogTitle="請輸入世界上最好的語言"
                android:key="et"
                android:summary="請輸入內容"
                android:title="請問你需要什麼語言" />
        </PreferenceScreen>
    </PreferenceCategory>

    <PreferenceCategory android:title="@string/app_name">
        <RingtonePreference
            android:key="ring"
            android:summary="選擇音樂"
            android:title="你見過魔法嗎?" />
    </PreferenceCategory>
</PreferenceScreen>

Pref1.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory android:title="JVM虛擬機器">
        <SwitchPreference
            android:key="gc"
            android:title="GC" />
        <SwitchPreference
            android:key="dump"
            android:title="dump" />

        <PreferenceScreen android:title="更多選項">
            <CheckBoxPreference
                android:key="top"
                android:title="Top" />
            <CheckBoxPreference
                android:key="mat"
                android:title="MAT" />
        </PreferenceScreen>
    </PreferenceCategory>

    <PreferenceCategory android:title="高效能JAVA">
        <MultiSelectListPreference
            android:entries="@array/list"
            android:entryValues="@array/list"
            android:summary="我是有意思的副標題"
            android:title="請選擇" />
    </PreferenceCategory>
</PreferenceScreen>

這裡寫圖片描述

Activity的啟動模式

模式 中文 說明
Standard 標準模式 是Activity的預設啟動模式,沒有特殊配置的Activity就會使用標準模式啟動。
SingleTop 棧頂複用模式 只有當Activity 位於棧頂 的時候,再次啟動當前的Activity,複用棧頂的Activity例項,不會重新建立,即部分單例模式;如果位於棧內,與標準模式相同
SingleTask 棧內複用模式 只要在棧中存在棧內複用模式的Activity,無論是在棧頂還是在棧內,多次呼叫時都會複用例項,不會重新建立,即完全的單例模式
SingleInstance 單例項模式 在啟動單例項模式的Activity的時候,系統為其建立一個單獨的任務棧,以後每次使用時都回使用這個單例,直到被銷燬,屬於真正的單例模式

注意:與棧內複用模式不同,棧內複用模式建立的任務棧並不獨享,仍可新增其他的Activity;而單例項模式所建立的任務棧只包含這個例項,所以說是真正的單例模式。

附錄