學習安卓開發[1] - 程序結構、Activity生命週期及頁面通信

一、程序結構

Android原生應用採用了MVC的架構設計模式,因此可以將一個Android APP中的對象歸爲Model、View或Controller中的一種。

具體到某個實際的APP結構中,它一般會由若干個activity、layout文件和自定義類組成,activity是Android SDK中Activity類的實例,負責管理用戶與應用界面的交互,應用的功能是通過編寫Activity子類來實現的;layout文件則用於定義需要顯示的UI對象以及指定它們在屏幕上所處的位置,layout文件的後綴爲XML。

由此可知,layout文件等屬於視圖對象,此外Android還自帶了很多可配置的視圖類,在後面逐步瞭解。控制器則通常是Activity、Fragment或Service的子類。

 

 

二、layout文件內容

layout文件定義了界面顯示的UI組件及其佈局方式,對於下面這樣一個簡單界面

 

其layout文件內容爲:

複製代碼

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">
    <TextView
        android:id="@+id/question_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="24dp" />
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/true_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/true_button" />
        <Button
            android:id="@+id/false_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/false_button" />
        <Button
            android:id="@+id/cheat_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/cheat_button"/>
        <Button
            android:id="@+id/next_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/next_button"
            android:drawableRight="@drawable/arrow_right"/>
    </LinearLayout>
</LinearLayout>

複製代碼

 

其組成有:

一個垂直的LinerLayout組件,包含一個TextView組件和一個水平的LinerLayout組件;

水平的LinerLayout組件中又包含4個Button組件。

先看一下這裏麪包含的一些後續會經常用到的屬性:

1. android:layout_width和android:layout_height,可以設置爲wrap_content(視圖與其父視圖大小相同)或match_content(視圖會根據其內容自動調整大小)。可以看到作爲根節點的LinerLayout也有layout_width和layout_height屬性,這是因爲Android系統爲其提供了容納整個應用的父視圖。

2.android:orientation,orientation是LinerLayout組件具有的屬性,它指定LinerLayout的子組件是水平放置還是水平放置。

3.android:text,TextView和Button具有text屬性,指定組件要顯示的文字內容。

 

三、字符串資源

可以看到android:text的值爲類似"@string/next_button"這樣的形式,這是對字符串資源的應用,字符串資源(string resource)在string.xml中定義。通過把字符串內容放置在字符串資源,然後再間接引用它們,這樣可以方便地修改需要顯示的內容,更重要的是便於應用的本地化。

比如@string/next_button在字符串資源中的形式爲:

<string name="next_button">Next</string>

那麼爲什麼在layout文件中輸入“@string/”後,Android會自動提示出“next_button”呢,這要從資源ID說起。非代碼形式的內容都屬於資源,比如圖像文件、音頻文件、XML文件等,資源文件都存放在app/res的子目錄下,string.xml的路徑爲app/res/values,layout.xml的路徑爲app/res/layout,要獲取這些xml中定義的資源需要先知道對應的資源ID,所有資源的ID都存放在R.java文件中,將Android Studio的項目視圖切換爲Project後,可根據路徑app/build/generated/source/r/debug/對於項目包名稱/R.java找到R文件,在這裏我們可以在public static final class string下找到

public static final int next_button=0x7f0b0025,這便是next_button的資源ID,資源ID都是int型。

R文件在編譯時自動生成,手動修改可能會導致未知錯誤。修改資源內容後,R文件不會實時刷新,只有在應用安裝到模擬器或物理設備時纔會重新生成,Android Studio還另外保存有一份用於代碼編譯的隱藏的R文件。

 

四、Activity

1.組件的引用

一個頁面的Activity與layout的名稱有對應關係,比如activity_quiz.xml對應的activity名稱爲QuizActivity.java。在Activity中使用組件的第一步,也是通過資源ID獲取該組件,比如引用一個Button時的代碼爲:

private Button mTrueButton;

...

mTrueButton=(Button) findViewById(R.id.true_button);

拿到組件後,就可以做後續的操作了,比如爲Button設置監聽器(listener):

mTrueButton.setOnClickListener(new View.OnClickListener(){

@Override

public void onClick(View v){

}

});

或者改變TextView的顯示內容:

mQuestionTextView=(TextView) findViewById(R.id.question_text_view);

mQuestionTextView.setText(“New Text”);

 

2.Activity的生命週期

在使用Android Studio嚮導創建一個Activity後,默認會有onCreate方法:

@Override

protected void onCreate(Bundle savedinstanceState){

}

onCreate屬於Activity的生命週期方法,此外還有onStart(), onResume(), onPause(), onStop(), onDestroy()。頁面在不同的狀態間切換時,這些方法會被Android系統執行

 

 

啓動APP時,依次執行onCreate, onStart, onResume,直接進入運行態;

按Home鍵回到主頁時,依次執行onPause, onStop,進入停止態;

點擊返回鍵退出APP時,則會依次執行onPause, onStop和onDestroy,頁面被銷燬;

 

需要注意的是,旋轉屏幕時也會依次執行onCreate, onStart, onResume,這是因爲發生屏幕旋轉時,Android會銷燬當前activity,尋找合適的備選資源並重新創建。這一特性對於需要保存頁面狀態的activity會造成問題,因爲重新創建activity會丟失當前頁面的操作狀態,這是我們不希望發生的。要解決這個問題,可以覆蓋系統的onSaveInstanceState(Bundle)方法,在APP轉入停止狀態時,這個方法在onStop之前由系統調用,我們可以在這個方法中將activity視圖狀態相關的數據存入Bundle對象中:

    @Override

    public void onSaveInstanceState(Bundle savedInstanceState) {

        super.onSaveInstanceState(savedInstanceState);

        savedInstanceState.putInt(KEY_INDEX, mCurrentIndex);

}

然後在每次重新創建activity時嘗試讀取Bundle中的內容:

  @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        if (savedInstanceState != null) {

            mCurrentIndex = savedInstanceState.getInt(KEY_INDEX);

        }

....

}

 

五、頁面通信

一般來說一個APP不可能只有一個頁面,通過主頁面打開子頁面時就涉及到了頁面間的通信。

Android使用基於Intent的通信方式,intent對象是component用來與操作系統通信的媒介工具。activity就是一種component對象。Intent是一種多用途通信工具,Intent類有多個構造方法,能滿足不同的使用需要。

 

1.從父頁面啓動子頁面

假設父頁面爲QuizActivity,子頁面爲CheatActivity,則從父頁面啓動子頁面的方法爲:

...

Intent intent = new Intent(QuizActivity.this, CheatActivity.class);

intent.putExtra(EXTRA_ANSWER_IS_TRUE, answerIsTrue);

startActivity(intent);

...

使用intent.putExtra方法可以在啓動子頁面的同時傳入需要的值,然後子頁面可讀取傳入值的方法爲:

mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE, false);

 

2.子頁面返回結果給父頁面

在很多場景中都需要子頁面返回結果給父頁面。有兩個方法可以使用:

public final void setResult(int resultCode)

public final void setResult(int resultCode, Intent data)

resultCode的值爲預定義常量,有:

Activity.RESULT_OK,對應確認操作

Activity.RESULT_CANCELED,對應取消操作

Activity.RESULT_FIRST_USER,用於自定義結果代碼

使用public final void setResult(int resultCode, Intent data)即可將結果數據通過Intent返回給父頁面。

相應的,在父頁面要取得子頁面的返回結果,需要覆蓋onActivityResult(int, int, Intent方法)

複製代碼

    @Override

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (resultCode != Activity.RESULT_OK) {

            return;

        }

        if (requestCode == REQUEST_CODE_CHEAT) {

            if (data == null) {

                return;

            }

            //TODO

        }

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