Android(11)——Android四大組件

Android

安卓開發者指南:https://developer.android.google.cn/guide

Android四大組件

Android常用四大組件:
1.Activity
2.Service
3.Content provider
4.Broadcast receiver

1 Activity

(1)一個Activity通常就是一個單獨的屏幕(窗口)。
(2)Activity之間通過Intent進行通信。
(3)android應用中每一個Activity都必須要在AndroidManifest.xml配置文件中聲明,否則系統將不識別也不執行該Activity。
之前的文章也有講到,回頭瞭解:https://blog.csdn.net/weixin_45044097/article/details/106695692

2 Service

(1)service用於在後臺完成用戶指定的操作。service分爲兩種:
(a)started(啓動):當應用程序組件(如activity)調用startService()方法啓動服務時,服務處於started狀態。
(b)bound(綁定):當應用程序組件調用bindService()方法綁定到服務時,服務處於bound狀態。

(2)startService() 與 bindService()區別:
(a)started service(啓動服務)是由其他組件調用startService()方法啓動的,這導致服務的onStartCommand()方法被調用。當服務是started狀態時,其生命週期與啓動它的組件無關,並且可以在後臺無限期運行,即使啓動服務的組件已經被銷燬。因此,服務需要在完成任務後調用stopSelf()方法停止,或者由其他組件調用stopService()方法停止。
(b)使用bindService()方法啓用服務,調用者與服務綁定在了一起,調用者一旦退出,服務也就終止,大有“不求同時生,必須同時死”的特點。

(3)開發人員需要在應用程序配置文件中聲明全部的service,使用< service>< /service>標籤。
(4)Service通常位於後臺運行,它一般不需要與用戶交互,因此Service組件沒有圖形用戶界面。Service組件需要繼承Service基類。Service組件通常用於爲其他組件提供後臺服務或監控其他組件的運行狀態。
來源:https://blog.csdn.net/ican87/article/details/21874321
這部分有個大概瞭解,之後再補充…

3 Content provider

(1)android平臺提供了Content Provider使一個應用程序的指定數據集提供給其他應用程序。其他應用可以通過ContentResolver類從該內容提供者中獲取或存入數據。

(2)只有需要在多個應用程序間共享數據是才需要內容提供者。例如,通訊錄數據被多個應用程序使用,且必須存儲在一個內容提供者中。它的好處是統一數據訪問方式。

(3)ContentProvider實現數據共享。ContentProvider用於保存和獲取數據,並使其對所有應用程序可見。這是不同應用程序間共享數據的唯一方式,因爲android沒有提供所有應用共同訪問的公共存儲區。

(4)開發人員不會直接使用ContentProvider類的對象,大多數是通過ContentResolver對象實現對ContentProvider的操作。

(5)ContentProvider使用URI來唯一標識其數據集,這裏的URI以content://作爲前綴,表示該數據由ContentProvider來管理。

來源:https://blog.csdn.net/ican87/article/details/21874321
這部分有個大概瞭解,之後再補充…

4 Broadcast receiver

4.1 概述

廣播被分爲兩種不同的類型:“普通廣播(Normal broadcasts)”和“有序廣播(Ordered broadcasts)”。
普通廣播是完全異步的,可以在同一時刻(邏輯上)被所有接收者接收到,消息傳遞的效率比較高,但缺點是:接收者不能將處理結果傳遞給下一個接收者,並且無法終止廣播Intent的傳播;
有序廣播是按照接收者聲明的優先級別(聲明在intent-filter元素的android:priority屬性中,數越大優先級別越高,取值範圍:-1000到1000。也可以調用IntentFilter對象的setPriority()進行設置),被接收者依次接收廣播。如:A的級別高於B,B的級別高於C,那麼,廣播先傳給A,再傳給B,最後傳給C。A得到廣播後,可以往廣播裏存入數據,當廣播傳給B時,B可以從廣播中得到A存入的數據。

作者:Lemon_95
鏈接:https://www.jianshu.com/p/51aaa65d5d25
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

(1)你的應用可以使用它對外部事件進行過濾,只對感興趣的外部事件(如當電話呼入時,或者數據網絡可用時)進行接收並做出響應。廣播接收器沒有用戶界面。然而,它們可以啓動一個activity或serice來響應它們收到的信息,或者用NotificationManager來通知用戶。通知可以用很多種方式來吸引用戶的注意力,例如閃動背燈、震動、播放聲音等。一般來說是在狀態欄上放一個持久的圖標,用戶可以打開它並獲取消息。
(2)廣播接收者的註冊有兩種方法,分別是程序動態註冊和AndroidManifest文件中進行靜態註冊。
(3)動態註冊廣播接收器特點是當用來註冊的Activity關掉後,廣播也就失效了。靜態註冊無需擔憂廣播接收器是否被關閉,只要設備是開啓狀態,廣播接收器也是打開着的。也就是說哪怕app本身未啓動,該app訂閱的廣播在觸發時也會對它起作用。

廣播分爲兩個角色:廣播發送者、廣播接受者

android 廣播:
1)用於不同組件間的通信(含:應用內/不同應用之間)
2)用於多線程通信
3)與android系統的通信

觀察者模式,廣播的機制:
在這裏插入圖片描述

4.2 生命週期

1.onReceive()
2.執行線程
3.執行時間限制

如果一個廣播處理完onReceive 那麼系統將認定此對象將不再是一個活動的對象,也就會finished掉它。

注意 :BroadcastReceiver生命週期很短,如果需要在onReceiver完成一些耗時操作,應該考慮在Service中開啓一個新線程處理耗時操作,不應該在BroadcastReceiver中開啓一個新的線程,因爲BroadcastReceiver生命週期很短,在執行完onReceiver以後就結束,如果開啓一個新的線程,可能出現BroadcastRecevier退出以後線程還在,而如果BroadcastReceiver所在的進程結束了,該線程就會被標記爲一個空線程,根據Android的內存管理策略,在系統內存緊張的時候,會按照優先級,結束優先級低的線程,而空線程無異是優先級最低的,這樣就可能導致BroadcastReceiver啓動的子線程不能執行完成。

4.3 廣播接收器註冊

註冊的方式有兩種:
➢靜態註冊:AndroidManifest.xml,8.0之後靜態註冊的限制
➢動態註冊:Java code

系統廣播
1.常見的系統廣播:開機廣播、網絡狀態、電池變化
2.發起者
3.接收者
4.使用步驟:註冊+接收+使用
5.演示(系統廣播+動態註冊)

如果要進行的操作需要花費比較長的時間,則不適合放在BroadcastReceiver中進行處理。
在 Android 中,程序的響應( Responsive )被活動管理器( Activity Manager )和窗口管理器( Window Manager )這兩個系統服務所監視。當 BroadcastReceiver 在 10 秒內沒有執行完畢,Android 會認爲該程序無響應。所以在 BroadcastReceiver 裏不能做一些比較耗時的操作,否側會彈出ANR ( Application No Response )的對話框。如果需要完成一項比較耗時的工作,應該通過發送Intent 給 Service ,由 Service 來完成。而不是使用子線程的方法來解決,因爲 BroadcastReceiver 的生命週期很短(在 onReceive() 執行後 BroadcastReceiver 的實例就會被銷燬),子線程可能還沒有結束BroadcastReceiver 就先結束了。如果 BroadcastReceiver 結束了,它的宿主進程還在運行,那麼子線程還會繼續執行。但宿主進程此時很容易在系統需要內存時被優先殺死,因爲它屬於空進程(沒有任何活動組件的進程)。

4.3.1 靜態註冊

註冊方式:在AndroidManifest.xml 裏通過< receiver> 標籤聲明:

<receiver
	//繼承BroadcastReceiver子類的類名
    android:name=".mBroadcastReceiver"
	android:enable="true"/"false"
	//此broadcastReceiver 是否接受其他應用發出的廣播
	//默認值時由receiver 中d有無inter-filter決定,如果有,默認true,否則默認false
	android:exported="true"/"false"
	android:icon="drawable resource"
	android:label="string resource"
	//具有相應權限的廣播發送者發送的廣播才能被此BroadcastReceiver所接收;
    android:permission="string"
	//BroadcastReceiver運行所處的進程
	//默認爲app的進程,可以指定獨立的進程
	//注:Android四大基本組件都可以通過此屬性指定自己的獨立進程
    android:process="string" >
	//用於指定此廣播接收器將接收的廣播類型
	 <intent-filter>
	 	// 開機廣播
	 	<action android:name="android.intent.action.BOOT_COMPLETED"/>
	 	// 電量低廣播
	 	<action android:name="android.intent.action.BATTERY_LOW"/>
	 	//接收網絡狀態改變時發出的廣播
		<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
	 	// 應用被安裝廣播
	 	<action android:name="android.intent.action.PACKAGE_INSTALL"/>
	 	// 應用被卸載廣播
	 	<action android:name="android.intent.action.BOOT_REMOVE"/>
	 	// 數據類型
	 	<data android:scheme="package"/>
	 </intent-filter>
 </receiver>

步驟:
1,自定義一個類繼承BroadcastReceiver
2,重寫onReceive方法
3,在manifest.xml中註冊

public class ImBroadcastReceiver extends BroadcastReceiver{
	private static final String TAG = "ImBroadcastReceiver";
	@Override
	public void onReceive(Context context, Intent intent) {
		// 接收廣播
		if(intent != null) {
			// 接收到的是什麼廣播
			String action = intent.getAction();
			Log.d(TAG,"onReceive: " + action);
		}
	}
}
4.3.2 動態註冊

註冊方式:在代碼中調用Context.registerReceiver() 方法,不需要在AndroidManifest.xml中聲明。

特別注意
動態廣播最好在onResume中註冊, onPause註銷
原因:
1、對於動態廣播,有註冊必然得有註銷,否則會導致內存泄漏
2、onPause在App死亡前一定會被執行,從而保證app死亡前一定會被註銷,從而防止內存泄漏

特別注意:
對於不同註冊方式的廣播接收器回調OnReceive(Context context,Intent intent)中的context返回值是不一樣的:
對於靜態註冊(全局+應用內廣播),回調onReceive(context, intent)中的context返回值是:ReceiverRestrictedContext;
對於全局廣播的動態註冊,回調onReceive(context, intent)中的context返回值是:ActivityContext;
對於應用內廣播的動態註冊(LocalBroadcastManager方式),回調onReceive(context, intent)中的context返回值是:Application Context。
對於應用內廣播的動態註冊(非LocalBroadcastManager方式),回調onReceive(context, intent)中的context返回值是:Activity Context;

4.3.3 區別

靜態註冊和動態註冊區別

動態註冊廣播不是常駐型廣播,也就是說廣播跟隨activity的生命週期。注意: 在activity結束前,移除廣播接收器。
靜態註冊是常駐型,也就是說當應用程序關閉後,如果有信息廣播來,程序也會被系統調用自動運行。
當廣播爲有序廣播時:
1 優先級高的先接收
2 同優先級的廣播接收器,動態優先於靜態
3 同優先級的同類廣播接收器,靜態:先掃描的優先於後掃描的,動態:先註冊的優先於後註冊的。
當廣播爲普通廣播時:
1 無視優先級,動態廣播接收器優先於靜態廣播接收器
2 同優先級的同類廣播接收器,靜態:先掃描的優先於後掃描的,動態:先註冊的優先於後註冊的。

廣播的發送 = 廣播發送者將此廣播的意圖(intent)通過 sendBroasdcast() 方法發送出去廣播的類型。

普通廣播、系統廣播、有序廣播、粘性廣播、App應用內廣播

4.4 自定義廣播

與系統廣播的區別:發起者、接受者不同

步驟:繼承BroadcastReceiver 基類;必須重寫抽象方法onReceive()方法

演示一(自定義廣播+動態註冊)
在這裏插入圖片描述
在這裏插入圖片描述
intentFilter.addAction(MY_ACTION)中String MY_ACTION="com.imooc.demo.adsd;"自定義的

演示二(兩個應用,一個發送,一個接收):APP間的廣播

1,廣播接收器收到相應廣播後,會自動調用onReceive() 方法
2,一般情況下,onReceive方法會會涉及與其他組件之間的交互,如 發送Notiotification,啓動server等
3,默認情況下,廣播接收器運行在UI線程,因此,onReceive方法不能執行耗時操作,否則將導致ANR

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