1、程序結構java
Android原生應用採用了MVC的架構設計模式,所以能夠將一個Android APP中的對象歸爲Model、View或Controller中的一種。android
具體到某個實際的APP結構中,它通常會由若干個activity、layout文件和自定義類組成,activity是Android SDK中Activity類的實例,負責管理用戶與應用界面的交互,應用的功能是經過編寫Activity子類來實現的;layout文件則用於定義須要顯示的UI對象以及指定它們在屏幕上所處的位置,layout文件的後綴爲XML。設計模式
由此可知,layout文件等屬於視圖對象,此外Android還自帶了不少可配置的視圖類,在後面逐步瞭解。控制器則一般是Activity、Fragment或Service的子類。架構
2、layout文件內容app
layout文件定義了界面顯示的UI組件及其佈局方式,對於下面這樣一個簡單界面ide
其layout文件內容爲:工具
複製代碼佈局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"ui
android:layout_width="match_parent"this
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屬性,指定組件要顯示的文字內容。
3、字符串資源
能夠看到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文件。
4、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);
}
....
}
5、頁面通訊
通常來講一個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
}
}