Android 應用程式的組成部分
Android應用程式由各個元件組成,並使用Manifest繫結到一起,Manifest描述了每一個元件和它們之間的互動方式,還用於指定許可權,硬體,平臺以及應用程式的後設資料等資訊。
應用程式的基本組成模組
- Activity
應用程式的表示層,程式的每一個UI都是通過Activity類來顯示的,Activity使用Fragment和檢視來佈局和顯示資訊,以及響應使用者的操作。
- Service
應該用程式中不可見的工作者 ,Service執行時沒有UI,可以更新資料來源和Activity,觸發通知和廣播Intent,用來執行執行時間長的任務或者不需要互動的任務。
- Content Provider
可共享的持久資料儲存器 。Content Provider用來管理和持久化應用程式資料,通常會與SQL資料庫互動。Content Provider是應用之間共享資料的首選方法。可以配置自己的Content Provider來允許其他應用程式訪問。
- Intent
應用程式間的訊息傳遞框架。Android 中大量使用了Intent,包括啟動和停止Activity和Service,在系統範圍內或向目標Activity、Service或Broadcast Receiver廣播訊息,以及請求對特定的一條資料執行操作。
- Broadcast Receiver
Intent偵聽器,主要用於接受廣播,接受特定事件,以便執行相應的操作
- Widget
通常新增到裝置主螢幕的視覺化應用程式元件。Widget是Broadcast Receiver的特殊變體,可用於建立動態的互動式應用程式元件,使用者可以把這些元件新增到主螢幕上。
- Notification
Notification允許向使用者傳送訊號,該元件是程式不可見或者不活動時吸引使用者注意的首選方法。
Manifest檔案
每個Android應用都有一個Manifest檔案,Manifest定義應用程式及其元件和需求的結構和後設資料。
它包含組成應用程式的每一個Activity、Service、Content Provider和Broadcast Receiver的節點,並使用Intent Filter和許可權來確定元件之間的以及這些元件和其他應用程式是如何互動的。Manifest檔案由一個根manifest標籤構成,該標籤有一個專案包的package屬性,該屬性作為改應用程式的唯一標識。
Manifest的各個屬性如下:
- versionCode
作為應用程式版本迭代的時候使用
- versionName
展示給使用者的公共版本號
- installLocation
指定是否允許將應用程式安裝到外部儲存器,可用引數preferExternal或auto,前者只要有可能就安裝在外部儲存器,後者由系統處理
- uses-sdk
定義minSDKVersion和targetSDKVersion,minSDKVersion保證在這個SDK版本及其以上執行,targetSDKVersion用於指定開發和測試應用程式時使用的平臺,儘可能設定該版本為最新的SDK版本。
- uses-feature
使用多個uses-feature來指定應用程式需要的每個硬體功能,如
<uses-feature android:name="android.hardware.microphone" android:required="false"/>
複製程式碼
還可以用來指定OpenGL的最低版本,版本號為32位,高16位為主版本號,低16位為次版本號,如
<uses-feature android:glEsVersion="0x00010001"/>
複製程式碼
- uses-permission
許可權申請,Android為了安全,在使用某些服務的時候需要許可權,如撥打電話,讀取聯絡人等
- application
一個Manifest只有一個application節點,application節點中包括了四大元件的子節點。
- activity
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
複製程式碼
- service
<service android:name=".MyService"/>
複製程式碼
- provider
<provider
android:authorities="com.fengwei.app.MyContentProvider"
android:name=".MyContentProvider"/>
複製程式碼
- receiver
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
</intent-filter>
</receiver>
複製程式碼
- uses-library
指定應用程式共享庫。
Android資原始檔
在Android res檔案目錄下包含drawable、values、layout檔案等,逐個介紹
- drawable
drawable資料夾下存放圖片資源,但Android碎片化嚴重,螢幕大小不一,解析度各不相同,所以會有不同解析度的drawable資料夾,如drawable-hdpi,drawable-xhdpi,drawable-xxhdpi等
- strings
<string name="title_draw_histogram">直方圖</string>
複製程式碼
- styles
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
複製程式碼
- colors
<color name="colorPrimary">#3F51B5</color>
複製程式碼
- dimens
<dimen name="large">16sp</dimen>
複製程式碼
- layout
佈局檔案,在XML檔案中設計使用者介面佈局,使介面和業務邏輯分離出來。
Android支援屬性動畫、補間動畫、幀動畫。
- 屬性動畫
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000"
android:interpolator="@android:anim/accelerate_interpolator"
android:propertyName="scaleX"
android:repeatCount="2"
android:repeatMode="reverse"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType" />
複製程式碼
- 補間動畫
動畫型別 | 屬性值 | 有效值 |
---|---|---|
Alpha | fromAlpha/toAlpha | 0~1 |
Scale | fromXScale/toXScale fromYScale/toYScale pivotX/pivotY(0%~100%) | 0~1 |
Translate | fromX/toX fromY/toY | 0~1 |
Rotate | fromDegrees/toDegrees pivotX/pivotY(0%~100%) | 0~360 |
- 幀動畫
建立Drawable的序列,做一個來連續的動畫。
執行時配置更改
Android執行時可以更改語言,位置,硬體,有時候預設行為不是很方便,如螢幕旋轉不希望重新建立Activity
要讓Activity可以監聽執行時配置更改,需要向它的manifest節點新增一個
android:configChanges
屬性,說明希望對哪些配置更改進行處理。
- mcc和mnc 檢測到SIM,並且它們的國家和網路發生了變化
- locale使用者改變了裝置的語言設定
- keyboardHidden顯示或者隱藏了鍵盤或其他輸入機制
- keboard對鍵盤型別進行了更改
- fontsize使用者更改了首選的字型大小
- uiMode整體UI模式發生了變化,黑白切換
- orientation螢幕發生了旋轉
- screenLayout螢幕佈局發生了變化
- screenSize可用螢幕尺寸改變
- smallersScreenSize物理螢幕尺寸改變
在特定情況下,多個事件可能同時觸發。
Activity 應用程式生命週期
每個Android應用程式都是通過自己的程式執行的,每一個程式都執行在獨立的Dalvik例項中。每一個應用程式的記憶體和程式管理都是由執行時處理的。程式被終止的順序由應用程式的優先順序決定的,一個應用程式的優先順序等同於它的優先順序最高的元件的優先順序。
當兩個應用程式有相同的優先順序時,在較低優先順序狀態執行時間最長的程式將會首先被終止。程式的優先順序也受到程式間依賴關係的影響。應用程式分為活動程式、可見程式、啟動Srevice程式,後臺程式、空程式。
- Active 程式
正在前臺執行的程式,這些程式數量非常少。Active程式包括:
-
處於活動狀態的Activity
-
正在執行OnReceive事件處理程式的BroadCast Receiver
-
正在執行onStart、onCreate、onDestroy事件處理程式的Service
-
正在執行,且已被標記為前臺執行的Service
- 可見程式
可見但是非活動程式,可以被使用者看到,但是不在前臺執行,如被dialog擋住的Actvity,這類程式數量也很少,不會輕易被終止。
- 啟動Service程式
已經啟動的Service程式,它們的優先順序低於可見Activity和前臺Service,在活動或者可見的程式需要資源時,會終止它們。當系統殺死一個Service後,會在資源可用時重啟該Service,除非告訴系統不這麼做(設定onStartCommand的返回值)
- 後臺程式
不可見,並且沒有任何執行Service或者Activity的程式,通常有很多這種程式,當前臺資源不夠時會優先終止它們。
- 空程式
Android會把生存週期結束後的應用程式儲存在記憶體中。目的是為了減少應用程式被再次啟動時的啟動時間。這些程式會被定期終止
Actvity的建立
一個Activity一個螢幕,Activity類呈現了一個封裝了視窗顯示處理功能的空白螢幕,需要UI控制元件進行填充,要把UI分給一個Activity需要在Actvity的onCreate方法中呼叫setContentView。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
複製程式碼
建立好了Actvity需要在Manifest註冊:
<activity
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
複製程式碼
Activity的生命週期
- Activity棧
每一個Activity的狀態由它在Activity棧中所處的位置決定,Activity棧是當前所有正在執行的Activity的集合。一個新的Activity啟動時,它就變為Activity類,並移動到棧頂。如果使用者點選了Back按鈕,會回到上一個Activity,上一個Activity就會回到棧頂,變為活動狀態。
[圖片上傳失敗…(image-fc5494-1513087424368)]
- Activity的狀態
隨著Activity的建立和銷燬,會在棧中進進出出,Activity會有四種狀態:
- 活動狀態
當Activity位於棧頂時,它是可見的,具有焦點的前臺Activity,這時與使用者進行互動,優先順序很高
- 暫停狀態
Activity可見,但是沒有獲得焦點,不能和使用者互動,但一個Activity完全不可見時,就處於停止狀態
- 停止狀態
Activity不可見,但其他地方需要記憶體時,它會成為被終止的首選物件,在停止狀態,儲存資料和當前UI的狀態以及停止一些不必要的操作是很重要的。
- 非活動狀態
Activity被終止之後,在啟動之前就處於非活動狀態,已經移出棧中。
- Activity狀態改變的監聽
Activity的事件處理程式如下,當Activity在完整的,可見的和活動的生存期之間轉化時,它們會被觸發。
public class Main2Activity extends AppCompatActivity {
//在完整生存期開始時呼叫
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//初始化一個Activity並填充UI
}
//在onCreate方法完成後呼叫,用於恢復UI狀態
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//從savedInstanceState恢復UI狀態
//這個Bundle也被傳遞給OnCreate
//自Activity上次可見後,只有當系統終止了該Activity時,才會被呼叫
//在隨後的Activity程式的可見生存期之前呼叫
}
@Override
protected void onRestart() {
super.onRestart();
//載入改變,知道Activity在此程式中已經可見
}
//在可見生存期開始時呼叫
@Override
protected void onStart() {
super.onStart();
//Activity可見,UI change
}
//在Activity 狀態生存期開始時呼叫
@Override
protected void onResume() {
super.onResume();
//恢復Activity需要,但是當它處於不活動狀態時被掛起,暫停UI更新,執行緒或者程式
//Activity狀態生命週期結束時呼叫,用來儲存UI狀態的改變
}
//把UI狀態改變儲存到outState
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//如果程式被執行時終止並被重啟,那麼這個Bundle將被傳遞給onCreate和onRestoreInstanceState
}
//在Activity狀態生存期結束時呼叫
@Override
protected void onPause() {
super.onPause();
//掛起不需要更新的UI更新,執行緒或者CPU密集的程式
//當Activity不是前臺的活動狀態的Activity時
}
//在可見生存期結束時呼叫
@Override
protected void onStop() {
super.onStop();
//掛起不需要的UI更新,執行緒或處理事件
//當Activity不可見時,儲存所有的編輯或者狀態改變
}
//在完整生存期結束時呼叫
@Override
protected void onDestroy() {
super.onDestroy();
//清理所有的資源,結束執行緒,關閉資料庫連線等
}
}
複製程式碼
- Activity生存期
在一個Activity從建立到銷燬的完整的生存期,它會經歷活動生存期和可見生存期的一次或者多次重複。
- 完整生命期
使用onCreate初始化Activity:填充使用者介面,獲得Fragment的引用,分配對類變數的引用,將資料繫結到控制元件,啟動service和定時器等。使用onDestory來清理onCreate建立的資源,關閉所有外部連線。
- 可見生存期
onStart和onStop之間的時間叫做可見生存期。Activity可見,但是沒有焦點,不能互動。
onStop方法中暫停或者停止動畫、執行緒、感測器監聽器、GPS查詢。定時器、Service或者更新UI的執行緒。
- 活動生存期
onResume和onPause之間的時間叫做活動生存期。Activity在前臺,接受使用者互動資訊。一般在onPause中儲存狀態,停止Broadcast Receiver,onResume中重新註冊Broadcast Receiver。