Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 四大組件之Activity(上)——Activity的生命周期、系統回收、系統配置改變的影響

四大組件之Activity(上)——Activity的生命周期、系統回收、系統配置改變的影響

編輯:關於Android編程

第1節 Activity的使用

Activity幾乎是每個應用必有的組件,所以任何安卓應用的開發幾乎都是從Activity開始的。

比如,你希望設計一個計算器應用,要呈現這個計算器的功能(顯示出計算器的樣子,實現計算的能力)一定會在這個應用中創建一個Activity,讓這個Activity展示的界面就是計算器。

開發者官網1

所以使用Android Studio創建工程以後,會默認為我們創建一個Activity組件,它繼承自Android SDK的Activity類。

class CalulatorActivity extends Activity
{
    ......
}

新創建的Activity—CalulatorActivity作為安卓的四大組件之一,一定要在這個應用的配置文件manifest.xml中聲明自己的存在,否則系統會不認識這個組件,當你啟動它的時候就會報錯。

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.anddle.calculator">

    <application android:icon="@mipmap/ic_launcher" android:label="@string/app_name">
        <activity android:name=".CalulatorActivity">
        ......
        </activity>
    </application>

</manifest>

第2節 Activity的生命周期

每一個Activity都有它的生命周期,體現了它從誕生到消亡的各個階段。

下圖為我們展示了Activity整個生命的過程,這是安卓官方提供的Activity生命周期圖。

開發者官網1

2.1 生命各個時期的回調

Activity每進入到一個生命的階段,就會調用這些狀態對應的函數。

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

 @Override
protected void onDestroy() {
   super.onDestroy();
}

@Override
protected void onResume() {
   super.onResume();
}

@Override
protected void onPause() {
   super.onPause();
}

@Override
protected void onStart() {
   super.onStart();
}

@Override
protected void onStop() {
   super.onStop();
}

@Override
protected void onRestart() {
   super.onRestart();
}

如果我們在代碼中繼承了Activity類,並覆蓋了這些函數,我們就能感知到Actvity生命狀態的轉換,並在這個轉換的時刻讓Activity做對應的處理。

比如在Activity創建的時候,讓它調用我們的代碼,完成界面的布局;在Activity銷毀的時候,讓它調用我們的代碼,完成界面資源的釋放。

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //進行界面的布局
        setContentView(R.layout.activity_main);
        ......
}

 @Override
protected void onDestroy() {
        super.onDestroy();
        //釋放一些界面可能占用的資源
        ......
}

2.2 Activity的狀態

接下來,我們詳細介紹下Acivity的各個階段。這些階段都是成對出現的。根據不同的標准,我們將它們分成三類:

全生命周期:這是Activity的從創建到銷毀的整個階段,從onCreate()開始到onDestroy()結束。

可見生命周期:這是Activity能被用戶看到的整個階段,這裡說的能被看到包括了“雖然被顯示但是不能與用戶交互”的情況,例如你正在微信聊天,突然系統彈出來一個對話框類型的Activity,提示你電量不足,這時微信界面被擋在後面,不能和用戶交互了,但是你還能看到。從onStart()開始到onStop()結束。

開發者官網1

前台生命周期:這是Activity可以和用戶進行交互的階段。從onResume()開始到onPause()結束。

\

2.3 Acivity常見的切換周期

2.3.1 完全周期

從一個Activity創建出來,到顯示,再到用戶按返回鍵主動退出銷毀這個Activity,它將經歷:
onCreate()->
onStart()->
onResume()->
用戶可以與Activity交互,用戶按返回鍵主動退出->
onPause()->
onStop()->
onDestroy()

2.3.2 Activity啟動另一個Activity

Activity A創建出來,並顯示;然後Activity A啟動另一個Activity B,B創建出來,並顯示,它將經歷:
Activity A onCreate()->
Activity A onStart()->
Activity A onResume()->
用戶可以與Activity A交互,然後Activity A啟動另一個Activity B,
Activity A onPause()->
Activity B onCreate()->
Activity B onStart()->
Activity B onResume()->
Activity A onSaveInstanceState()->
Activity A onStop()->
Activity A被隱藏,用戶可以與Activity B交互;

2.3.3 Activity屏幕旋轉

如果一個Activity從創建出來,到顯示,然後旋轉,那麼它將經歷:
onCreate()->
onStart()->
onResume()->
用戶可以與Activity交互,此時屏幕進行旋轉,從豎屏變橫屏->
onPause()->
onSaveInstanceState()->
onStop()->
onDestroy()->
onCreate()->
onStart()->
onRestoreInstanceState()->
onResume()->
用戶可以與Activity交互;

在周期變化的過程當中,加入了onSaveInstanceState()onRestoreInstanceState()。雖然它們不是Activity周期的一部分,但是對它們對回調在Activity的各種切換扮演了非常重要的角色--提供了保存Activity數據的時機。

第3節 Activity的系統回收

在Activity生命的周期中,安卓系統可能直接回收Activity。系統回收Activity有兩種常見的情況,

系統資源緊張; 屏幕的旋轉;

3.1 資源緊張

當系統資源緊張的時候,例如你打開了很多應用,系統中的可用內存很少了。這是安卓系統會采用一個策略來回收系統中的資源。

對於那些沒有顯示或者雖然顯示了、但卻沒有和用戶做交互的Activity們,系統會優先回收那些沒有顯示的Activity(例如在onStop()狀態下的Activity);

如果回收那些資源以後,發現資源還是不夠用,就會回收雖然顯示了、但卻沒有和用戶做交互的Activity(例如在onPause()狀態下的)。

開發者官網1

這裡會遇到一個問題:假如Activity A啟動了Activity B之後,系統發現內存不足,在回收了其它所有資源後,它不得不繼續回收Activity A。

3.1.1 產生的問題

此時與Acitity B正在交互的用戶,點擊了“返回”按鈕,按照道理,應該顯示Activity A才對,但是系統已經回收了Activity A。這時該怎麼辦呢?

開發者官網1

系統遇到這種情況就會重新創建Activity A,重新調用它的onCreate()。

不過這裡又會遇到另一個很現實的問題:如果之前的Activity A上面用戶正輸入了一些東西,例如他的名字和郵箱地址,或者是已經編輯了很長一大段的文字,如果系統onCreate的話,這些輸入的東西就會被清除掉了。這可怎麼辦呢?

3.1.2 解決辦法

安卓系統為我們提供了一個這種情況下數據的重建機制:在Activity被放到後台運行的時候使用onSaveInstanceState()回調函數來保存這些數據,

@Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
   super.onSaveInstanceState(savedInstanceState);
   //將要保存的數據,例如撰寫的文檔的字符串,保存到savedInstanceState變量當中
}

在Activity被重建的時候,使用onRestoreInstanceState()回調函數來恢復這些數據

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
   super.onRestoreInstanceState(savedInstanceState);
   //將需要恢復的數據,例如文檔字符串,從savedInstanceState變量中取出,設置到界面上
}

需要注意的是,onSaveInstanceState()onRestoreInstanceState()在Activity周期切換過程中並不一定會被調用,只是在這種Activity異常流程處理時(Activity被系統回收、config信息變化等情況),才會被調用到。

3.2 屏幕旋轉

屏幕旋轉時,Activity的生命周期也將發生變化。

如果一個Activity從創建出來,到顯示,然後旋轉,那麼它將經歷:
onCreate()->
onStart()->
onResume()->
用戶可以與Activity交互,此時屏幕進行旋轉,從豎屏變橫屏->
onPause()->
onSaveInstanceState()->
onStop()->
onDestroy()->
onCreate()->
onStart()->
onRestoreInstanceState()->
onResume()->
用戶可以與Activity交互;

可以看到,旋轉的時候onCreate()函數會被再次調用。在這裡,如果擁有橫屏布局文件,onCreate()中的setContentView()將會使用橫屏的布局,如果沒有,依然使用默認的布局文件。

3.2.1 產生的問題

如果Activity從豎屏變成橫屏,那麼會先執行onDestroy(),再進行一次onCreate()創建的過程。這意味著之前界面上顯示的數據需要重新刷新一次。

假如之前刷新這些數據需要花費很長的時間,那就有必要認真的思考如何避免數據的再次刷新。

3.2.2 解決方法

解決屏幕旋轉時Activity被create兩次的方法有兩種。

onSaveInstanceState()onRestoreInstanceState()可用用來保存和還原這些數據;

AndroidManifest.xml文件中,給這個Activity組件加上android:screenOrientation="orientation|screenSize"的屬性就可以了;



    
        
        
        ......
    

這種Activity從創建出來,到顯示,然後旋轉,那麼它將經歷:
onCreate()->
onStart()->
onResume()->
用戶可以與Activity交互,此時屏幕進行旋轉,從豎屏變橫屏->
onConfigurationChanged();

如此一來,這個Activity在旋轉時就不會重走銷毀、創建的過程了,而只是在旋轉後經歷一個onConfigurationChanged()。這種情況下,如果存在它對應的橫屏布局文件,那麼這個布局也不會被使用到,因為onCreate()並沒有被調用到。

第4節 系統設置改變

當設備的系統設置發生變化時,例如橫豎屏切換、語言變化,可以被Activity感知到。

4.1 監聽系統設置改變

系統設置發生變化可以通知到Activity,

AndroidManifest.xml文件當中,給對應的Activity標簽,添加android:configChanges屬性,例如


    android:configChanges="screenSize|orientation">

在需要在實現Activity的代碼中做出相應的修改:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    //從newConfig中獲取感興趣的系統配置變化事件,例如屏幕方向是否變化,系統語言是否變化等等
    if(Configuration.ORIENTATION_PORTRAIT == 
            newConfig.orientation) {

    }
}

在manifest中指定關注的是screenSizeorientation,那麼當手機從橫屏變化成豎屏(或者豎屏變化成橫屏)的時候,這個函數就會被調用,就可以在這裡添加我們需要的代碼。

系統變化的種類很多,除了screenSizeorientation還有:keyboardHidden locale fontScale等等。

4.2 設備旋轉

我們可以用兩種方法處理設備的旋轉,

讓Activity不跟隨設備方向的旋轉而旋轉,它只有豎屏(或只有橫屏)的界面。要做到這一點很容易,在AndroidManifest.xml文件中,給這個Activity組件加上android:screenOrientation="portrait"
(保持豎屏)或者android:screenOrientation="landscape"
(保持橫屏)的屬性就可以了;

<code class="language-xml hljs "><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.anddle.anddleplayer">
    <application ......="">
        <activity android:name=".VideoListActivity" android:screenorientation="landscape">
        </activity>
        ......
    </application>
</manifest></code>

讓Activity跟隨設備方向的旋轉而旋轉。
采用章節3.2中介紹的方法。

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