1. 程式人生 > >Android第一行代碼學習筆記七---活動的生命周期

Android第一行代碼學習筆記七---活動的生命周期

帶來 並不是 androi style 屏幕 ide instance 定位 -o

@1.返回棧

Android中的活動是可以層疊的,我們每啟動一個新的活動,就會覆蓋在原活動之上,然後點擊Back鍵就會銷毀最上面的活動,下面一個活動就會重新顯示出來。

Android是使用任務(Task)來管理活動的,一個任務就是一組存放在棧裏的活動的集合,這個棧也被稱為返回棧(Back Stack)。棧是一種後進先出的數據結構,在默認情況下,每當我們啟動了一個新的活動,它會在返回棧中入棧,並處於棧頂的位置。而當我們按下Back鍵或調用finish()方法去銷毀一個活動時,處於棧頂的活動會出棧,這時前一個入棧的活動就會重新處於棧頂的位置。系統總是會顯示處於棧頂的活動給用戶。

@2.活動狀態:每個活動在其生命周期中最多可能會有4種狀態。

a:運行狀態:當一個活動位於返回棧的棧頂時,這時活動就處於運行狀態。系統最不願意回收的就是處於運行狀態的活動,因為這會帶來非常差的用戶體驗。

b:暫停狀態:當一個活動不再處於棧頂位置,但仍然可見時,這時活動就進入了暫停狀態。這是因為並不是每一個活動都會占滿整個屏幕,比如對話框形式的活動只會占用屏幕中間的部分區域。處於暫停狀態的活動仍然是完全存活的,系統也不願意回收這種活動,只有在內存極低的狀況下,系統才會考慮去回收這種活動。

c:停止狀態:當一個活動不再處於棧頂位置,並且完全不可見的時候就進入了停止狀態。系統仍然會為這種活動保存相應的狀態和成員變量,但是這並不是完全可靠的,當其它地方需要內存時,處於停止狀態的活動有可能會被系統回收。

d:銷毀狀態:當一個從返回棧中移除後就變成了銷毀狀態。系統會最傾向於回收處於這種狀態的活動,從而保證手機的內存充足。

@3:活動的生存期.技術分享

Activity類定義了7個回調方法,覆蓋了活動生命周期的每一個環節

@1-onCreate():每個活動中都重寫了這個方法,它會在活動第一次被創建的時候調用,你應該在這個方法中完成活動的初始化操作,比如說加載布局、綁定事件。

@2-onStart():這個方法在活動由不可見變為可見的時候調用。、

@3-onResume():這個活動早活動準備好和用戶進行交互的時候調用。此時的活動一定位於返回棧的棧頂,並且處於運行狀態。

@4-onPause():這個方法在系統準備去啟動或者恢復另一個活動的時候調用。我們通常會在這個方法中將一些消耗CPU的資源釋放掉,以及保存一些關鍵數據,但這個方法的執行速度一定要快,不然會影響到新的棧頂活動的使用。

@5-onStop():這個方法在活動完全不可見的時候調用。它和onPause()方法的區別在於,如果啟動的新活動是一個對話框式的活動,那麽onPause()方法會得到執行,而onStop()方法並不會執行。

@6-onDestroy():這個方法在活動被銷毀之前調用,之後活動的狀態變為銷毀狀態。

@7-onRestart():這個方法在活動由停止狀態變為運行狀態之前調用,也就是活動被重新啟動了。

以上7個方法中除了onRestart()方法外,其它都是兩兩相對,從而又可以將活動分為3中生存期。

完整生存期:活動在onCreate()和onDestroy()之間所經歷的,就是完整生存期,一般情況下,一個活動會在onCreate()方法中完成各種初始化操作,而在onDestroy()方法中完成釋放內存的操作。

可見生存期:活動在onStart()和onStop()之間所經歷的就是可見生存期,在可見生存期內活動對用戶是可見的,即便有可能無法和用戶交互。

前臺生存期:活動在onResume()方法和onPause()方法之間經歷的就是前臺生存期。在前臺生存期內,活動總是處於運行狀態的,此時的活動是可以和用戶進行交互的,我們平時看到和接觸最多的也就是這個狀態下的活動。

@4.體驗活動的生命周期

新建ActivityCycleTest項目,子活動NormalActivity和DialogActivity,子活動布局為normal_layout和dialog_layout,編輯normal_layout.xml文件,將裏面的內容替換成如下內容:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="this is a normal Activity"/>

</LinearLayout>

編輯dialog_layout.xml文件,將裏面的內容替換成如下內容:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="this is a dialog Activity"/>
</LinearLayout>

修改AndroidManifest.xml的<activity>標簽的配置如下:

<activity android:name=".DialogActivity"
            android:theme="@android:style/Theme.Dialog">
/activity>

修改activity_main.xml,在LinearLayout中加入了兩個按鈕,一個用於啟動NormalActivity,一個啟動DialogActivity。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<Button
    android:id="@+id/start_normal_activity"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Start Normal Activity"/>
    <Button
        android:id="@+id/start_dialog_activity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Start Dialog Activity"/>
</LinearLayout>

修改MainActivity中的代碼:

public class MainActivity extends AppCompatActivity {

    public static final String TAG="MainActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button startNormalActivity=(Button)findViewById(R.id.start_normal_activity);
        final Button startDialogActivity=(Button)findViewById(R.id.start_dialog_activity);
        startNormalActivity.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent =new Intent(MainActivity.this,NormalActivity.class);
                startActivity(intent);
            }
        });
        startDialogActivity.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                Intent intent=new Intent(MainActivity.this,DialogActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG,"onStart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG,"onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG,"onPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG,"onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG,"onDestroy");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d(TAG,"onRestart");
    }
}

運行程序,觀察logcat的打印日誌,MainActivity第一次創建時會執行onCreate()、onStart()、和onResume()方法

技術分享

點擊第一個按鈕啟動NormalActivity,由於NormalActivity已經完全遮擋住MainActivity,因此onPause()和onStop()方法都會執行

技術分享

back鍵回到MainActivity,由於之前MainActivity已經進入了停止狀態,所以onRestart方法會得到執行,之後一次執行onStart()和onResume()方法,此時onCreate(0方法不會執行,因為MainActivity並沒有重新創建

技術分享

點擊第二個按鈕啟動DialogActivity,只有onPause(0方法得到執行,onStop()方法並沒有執行,因為DialogActivity並沒有完全遮擋住MainActivity,此時MainActivity只是進入了暫停狀態,並沒有進入停止狀態。相應的按下back鍵只有onResume()方法得到執行

Android第一行代碼學習筆記七---活動的生命周期