[TOC]
# 目錄
# 1、Android四大組件
* ### **Activity(活動)**
**需要在AndroidMainfest.xml中注冊**
**概念:**Activity是Android應用與用戶進行交互的最直接的組件,它提供了應用的界面顯示以及用戶的點擊等動作的回調,對于用戶是可見的。Activity是Context的子類,同時是實現了window.callback和keyevent.callback以處理與用戶的交互。
```
<activity android:name=".MainActivity" android:label="@string/app_name">
<!-- 主Activity -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
```
**生命周期:**
> 推薦閱讀:[https://developer.android.com/training/basics/activity-lifecycle/](https://developer.android.com/training/basics/activity-lifecycle/ "https://developer.android.com/training/basics/activity-lifecycle/")
[](https://developer.android.com/training/basics/activity-lifecycle/)**Activity的狀態保存:**
* 正常情況下或者用戶主動按返回鍵,或者點擊關閉按鈕(實現了finish( )方法)退出Activity,使用onPause( ) 和onStop( )去保存數據
* 非正常情況下(系統內存不足,主動kill掉處于暫停或者停止狀態的Activity)導致的Activity退出,需要我們重寫onSaveInstanceState( Bundle savedInstanceState)方法去保存數據,然后在OnCreate(Bundle savedInstanceState)方法中或者實現在系統onStart( )方法調用后,去調用的OnRestoreInsatnceState(Bundle savedInstanceState)去對數據進行還原
**Activity的啟動模式**
* **standred:默認模式,**不用為Activity配置android:launchModel屬性,每啟動一次就會創建一個實例
* **singleTop:棧頂復用模式**,需要在AndroidMainfest.xml中為該Activity配置**android:launchModel="singleTop"**屬性,每次啟動時,會先去判斷當前**返回棧的棧頂**是否是該Activity的實例,如果不是的話就創建一個新的實例,是的話就不會創建新的實例,而是使用當前的棧頂實例。(會調用onNewIntent()方法)
* **singleTask:棧內復用模式**,需要在AndroidMainfest.xml中為該Activity配置**android:launchModel="singleTask"**屬性,每次啟動時,會先去判斷當前**返回棧內**是否存在該Activity的實例,如果不存在的話就創建一個新的實例,置于棧頂,如果棧內存在該Activity實例的話就會將該實例上面的所有Activity實例進行出棧操作,將該Activity實例置于棧頂(會調用onNewIntent()方法)
* **singleInstance:實例唯一模式**,在整個應用中只有一個該Activity的實例,在初次啟動該Activity時,會為該Activity開辟一個新的棧空間,將該Activity置于新空間內,之后每次再去啟動該Activity時,去新空間中尋找該Activity實例
* ### **Service(服務)**
**需要在AndroidMainfest.xml中注冊**
Service也是Context的子類,用于處理后臺任務的,用戶是不可見的。
**Service的創建**
1. **手動創建**
* 新建Class文件,繼承Service
* 在AndroidMainfest中進行注冊
2. **使用AndroidStudio進行自動創建**
AndroidMainfest.xml
```
<service
android:name=".MyService" //Service所在的類
android:enabled="true" //Service是否可用
android:exported="true" //是否可以被其他應用使用
/>
```
**Service的生命周期**

**Service的生命周期函數**
* **OnCreate()**?當Service被創建時調用,在一次生命周期過程中只調用一次
* **OnStartCommand()**?當在Activity中調用startService()時被調用,一般用與Activity無關的Service,如播放音樂,下載等
* **OnBind()**?在Activity調用bindService()函數時調用
* **OnUnBind()**?在Activity調用unBindService()函數時調用
* **OnDestory()**?在Service銷毀時調用,再次啟動該Service時,需調用OnCreate()方法
由圖可知,service有兩種模式,綁定模式和非綁定模式。
1. 綁定模式***(bindService())***的生命周期:onCreate( ) => onBind( ) => onUnbind( ) => onDestory( )
2. 非綁定模式***(startService())***的生命周期: onCreate( ) => onStartCommand( ) => onDestory( )
> 如果一個service執行了由多個Activity執行了onBind( ) 方法,那么需要所有的Activity都執行onUnBind( )方法,這個service才會停止
>
> 如果一個service執行了由多個Activity執行了startService( ) 方法,只需要執行一次stopService()或者stopSelf()方法,這個service就會停止,因為不管執行多少次啟動,只會調用一次onCreate( )方法
**IntentService**
IntentService是Service的子類,比普通的Service增加了額外的功能,IntentService**會創建獨立的線程來處理所有的Intent請求**,**會創建獨立的線程來處理onHandleIntent( )中實現的代碼**,除此之外,IntentService還**會自動停止。**
**前臺服務** Android O之后必須加上 channelld,前臺服務才可生效
* ### **ContentProvider(內容提供器)**
是應用于app之間的共享數據的接口,使用時必須自定義一個類繼承ContentProvicer,然后重寫query、insert、update、delete等方法
**必須在AndroidMainfest.xml中注冊**
ContentProvider與SQLite的最大區別在于:SQLite只能訪問本應用下的數據庫,而ContentProvider還可以去增刪改查本地文件、xml文件的讀取等
* ### **BroadCastReceiver(廣播接收器)**
**在AndroidMainfest.xml中注冊稱為靜態注冊,在代碼中注冊稱為動態注冊,各有優劣**
接收系統或者app發送的廣播事件,分為有序廣播和無序廣播。
實現原理:通過Android系統的Binder機制實現通信
> **有序廣播:**按照被接受者的優先級順序在被接受者之間依次傳播,高優先級的被接受者可以將處理結果通過廣播傳遞給低優先級的被接受者,也可以中斷該廣播的傳遞
>
> **無序廣播:** 完全異步,理論上可以被任何廣播接收器接受到,優點是:傳播效率高,缺點是不可控,
```
<!-- 靜態注冊 -->
<receiver android:name=".receiver1">
<!-- 該廣播接收器接收的廣播 -->
<!-- android:priority 設置優先級 -->
<intent-filter android:priority="100">
<action android:name="android.intent.action.CALL"></action>
</intent-filter>
</receiver>
```
```
//動態注冊
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//to do something
}
};
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_CALL);//該廣播接收器接收的廣播類型
//intentFilter.setPriority(100); //為廣播設置優先級
registerReceiver(receiver,intentFilter);
```
```
Intent intent = new Intent("com.duoshilin.android.week03.MY_BROADCAST");
sendBroadcast(intent); //發送無序廣播
sendOrderedBroadcast(intent,null);//發送有序廣播 第二個參數是與權限有關的字符串
```
##### **本地廣播**
* 只能動態注冊不能靜態注冊
* 只能在本應用中使用
```
/**
* 使用本地廣播
*/
public class Main2Activity extends AppCompatActivity {
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
private LocalBroadcastManager manager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
//注冊一個本地廣播
manager = LocalBroadcastManager.getInstance(this);
intentFilter = new IntentFilter();
intentFilter.addAction("com.duoshilin.android.LOCAL_BROCAST");
localReceiver=new LocalReceiver();
manager.registerReceiver(localReceiver,intentFilter);
//點擊按鈕發送廣播
Button button = findViewById(R.id.send_local_broadcast);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.duoshilin.android.LOCAL_BROCAST");
manager.sendBroadcast(intent);
}
});
}
class LocalReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "我是一個本地廣播", Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
manager.unregisterReceiver(localReceiver);
}
}
```
# 2、AndroidMainfest.xml
> 官方文檔:[https://developer.android.com/guide/topics/manifest/manifest-intro](https://developer.android.com/guide/topics/manifest/manifest-intro "https://developer.android.com/guide/topics/manifest/manifest-intro")
# 3、Handler機制
* **是Android中消息傳遞 / 異步通信的機制,主要用于將子線程(工作線程)中需要更新UI的消息,傳遞給主線程(線程),從而實現對UI的更新(**android 中不允許子線程更新UI**)**
* **handler的使用必須先調用Looper.prepare()方法,通常在Activity中調用時沒有調用該方法是因為在ActivityThread的main方法中,系統內部調用了Looper.prepareMainLooper()方法,實際上還是調用了Looper.prepare()**
* **handler的使用**
```
public class HandlerTestActivity extends AppCompatActivity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler_test);
tv=findViewById(R.id.tv);
method1();
method2();
method3();
}
//匿名內部類實現
private void method1(){
final Handler mHandler;
mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
Bundle data = msg.getData();
tv.setText(data.getString("key"));
}
};
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message message = new Message();
message.obj = "匿名實現的Handler";
Bundle data = new Bundle();
data.putString("key","value");
message.setData(data);
mHandler.sendMessage(message);
}
}).start();
}
//新建Handler子類實現
private void method2(){
final Handler mHandler;
class MyHandler extends Handler{
@Override
public void handleMessage(Message msg) {
tv.setText(msg.obj.toString());
}
}
mHandler = new MyHandler();
new Thread(new Runnable() {
@Override
public void run() {
Message message = new Message();
message.obj = "Handler子類實現的Handler";
mHandler.sendMessageDelayed(message,2000);
}
}).start();
}
//使用Handler的post()實現
private void method3(){
Handler mHandler;
mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
tv.setText("使用handler.post()實現");
}
},3000);
}
}
```
**在子線程里使用Handler**
```
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
```
# 4、Handler、Message和Looper
> 推薦閱讀:[https://blog.csdn.net/fnhfire_7030/article/details/79518819](https://blog.csdn.net/fnhfire_7030/article/details/79518819 "https://blog.csdn.net/fnhfire_7030/article/details/79518819")
* Handler:負責發送和處理消息。
* Message:用來攜帶需要的數據。
* MessageQueue:消息隊列,隊列里面的內容就是Message。
* Looper:消息輪巡器,負責不停的從MessageQueue中取Message。

