日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android四大组件之广播接收器BroadcastReceiver

發布時間:2024/1/1 Android 73 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android四大组件之广播接收器BroadcastReceiver 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Android系統的廣播有一個全局監聽器,專門用于監聽/接收應用程序發出的廣播消息。

廣播的作用

  • 可以實現不同組件之間的通信(這些組件可以是同一應用內的或不同應用內的。)
  • 多線程通信
  • 與Android系統通信,如電話呼入、網絡可用時等。

廣播的通信模型

廣播的使用流程

自定義廣播接收者BroadcastReceiver

(1)繼承BroadcastReceiver
(2)重寫onReceive()方法

public class MyBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// 廣播接收器接收到相應廣播后,會自動回調 onReceive() 方法// 一般情況下,onReceive方法會涉及與其他組件之間的交互,如發送Notification、啟動Service等// 默認情況下,廣播接收器運行在UI線程,因此,onReceive()方法不能執行耗時操作,否則將導致ANR// TODO 實現與其他組件之間的交互,如發送Notification、啟動Service等} }

注意: 默認情況下,廣播接收器運行在UI線程,因此,onReceive()方法不能執行耗時操作,否則將導致ANR。

廣播接收者注冊

類型注冊方式特點應用場景
靜態注冊在AndroidManifest.xml里通過標簽聲明常駐,不受任何組件的生命周期影響,即使應用程序關閉后,有廣播消息來,程序依舊會被系統調用。缺點:耗電、占內存需要時刻監聽廣播
動態注冊在代碼中調用Context.registerReceiver()方法不常駐,生命周期跟隨組件變化 ,組件結束,廣播就結束,在組件結束前,必須移除廣播接收者,否則會造成內存泄漏在特定時刻需要監聽廣播

靜態注冊:

// 用于指定此廣播接收器將接收的廣播類型// 本示例中給出的是用于接收網絡狀態改變時發出的廣播<receiver android:name=".MyBroadcastReceiver"><intent-filter><action android:name="android.net.conn.CONNECTIVITY_CHANGE"/></intent-filter></receiver>

屬性說明:

<receiver// 能否接收其他App發出的廣播 // 默認值是由receiver中有無intent-filter決定的:如果有的話,為true,否則為falseandroid:enabled=["true" | "false"]android:exported=["true" | "false"]android:icon="drawable resource"android:label="string resource"// 繼承BroadcastReceiver子類的類名android:name=".mBroadcastReceiver"// 具有相應權限的廣播發送者發送的廣播才能被此BroadcastReceiver所接收;android:permission="string"// BroadcastReceiver運行所處的進程// 默認為app的進程,可以指定獨立的進程// 注:Android四大基本組件都可以通過此屬性指定自己的獨立進程android:process="string" >// 指定此廣播接收者將接收的廣播類型<receiver android:name=".MyBroadcastReceiver"><intent-filter><action android:name="android.net.conn.CONNECTIVITY_CHANGE"/></intent-filter></receiver> </receiver>

動態注冊:
動態廣播最好在Activity 的 onResume()注冊、onPause()注銷。有注冊就必然得有注銷,否則會導致內存泄漏。重復注冊、注銷是不允許出現的

  • 之所以不在onCreate() & onDestory() 或 onStart() & onStop()注冊、注銷是因為:
    當系統因為內存不足時要回收Activity占用的資源時,Activity在執行完onPause()方法后就會被銷毀,有些生命周期方法onStop(),onDestory()就不會執行。當再回到此Activity時,是從onCreate方法開始執行。如:

    假設我們將廣播的注銷放在onStop(),onDestory()方法里的話,有可能在Activity被銷毀后還未執行onStop(),onDestory()方法,即廣播仍還未注銷,從而導致內存泄露。但是,onPause()一定會被執行,從而保證了廣播在App銷毀前一定會被注銷,從而防止了內存泄露。

public class MainActivity extends AppCompatActivity {private MyBroadcastReceiver myBroadcastReceiver;@Overrideprotected void onResume() {super.onResume();// 1. 實例化BroadcastReceiver子類和IntentFiltermyBroadcastReceiver = new MyBroadcastReceiver();IntentFilter intentFilter = new IntentFilter();// 2. 設置接收廣播的類型intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");// 3. 動態注冊:調用Context的registerReceiver()方法registerReceiver(myBroadcastReceiver, intentFilter);}// 注冊廣播后,要在相應位置記得銷毀廣播// 即在onPause() 中unregisterReceiver(mBroadcastReceiver)// 當此Activity實例化時,會動態將MyBroadcastReceiver注冊到系統中// 當此Activity銷毀時,動態注冊的MyBroadcastReceiver將不再接收到相應的廣播。@Overrideprotected void onPause() {super.onPause();//銷毀在onResume()方法中的廣播unregisterReceiver(myBroadcastReceiver);} }

廣播的類型

類型說明
普通廣播(Normal Broadcast)自定義 intent的廣播(最常用)
系統廣播(System Broadcast)Android中內置的系統廣播,如開機、網絡狀態變化、拍照等等,每個廣播都有特定的intent-filter和具體的action
有序廣播(Ordered Broadcast)發送出去的廣播被廣播接收者按照先后順序接收
App應用內廣播(Local Broadcast)廣播的發送者和接收者都同屬于一個App。

普通廣播示例

發送廣播如下:

Intent intent = new Intent(); // 對應BroadcastReceiver中intentFilter的action intent.setAction(BROADCAST_ACTION); // 發送廣播 sendBroadcast(intent);

完整例子:
MyBroadcastReceiver:

public class MyBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// 廣播接收器接收到相應廣播后,會自動回調 onReceive() 方法// 一般情況下,onReceive方法會涉及與其他組件之間的交互,如發送Notification、啟動Service等// 默認情況下,廣播接收器運行在UI線程,因此,onReceive()方法不能執行耗時操作,否則將導致ANR// TODO 實現與其他組件之間的交互,如發送Notification、啟動Service等Toast.makeText(context,intent.getStringExtra("name"),Toast.LENGTH_LONG).show();} }

注冊、注銷和發送廣播:

public class MainActivity extends AppCompatActivity {private MyBroadcastReceiver myBroadcastReceiver;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 發廣播findViewById(R.id.me).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();intent.putExtra("name","wongkyunban");// 對應BroadcastReceiver中intentFilter的actionintent.setAction("com.haha.haha.this.is.my.broadcast");// 發送廣播sendBroadcast(intent);}});}// 注冊@Overrideprotected void onResume() {super.onResume();// 1. 實例化BroadcastReceiver子類和IntentFiltermyBroadcastReceiver = new MyBroadcastReceiver();IntentFilter intentFilter = new IntentFilter();// 2. 設置接收廣播的類型,自定義一個廣播intentFilter.addAction("com.haha.haha.this.is.my.broadcast");// 3. 動態注冊:調用Context的registerReceiver()方法registerReceiver(myBroadcastReceiver, intentFilter);}// 注銷// 注冊廣播后,要在相應位置記得銷毀廣播// 即在onPause() 中unregisterReceiver(mBroadcastReceiver)// 當此Activity實例化時,會動態將MyBroadcastReceiver注冊到系統中// 當此Activity銷毀時,動態注冊的MyBroadcastReceiver將不再接收到相應的廣播。@Overrideprotected void onPause() {super.onPause();//銷毀在onResume()方法中的廣播unregisterReceiver(myBroadcastReceiver);} }

注意:
若發送廣播有相應權限,那么廣播接收者也需要相應權限,通過屬性字段配置的。

有序廣播示例

廣播接收者接收廣播的順序規則:

  • 按照Priority屬性值從大-小排序;
  • Priority屬性相同者,動態注冊的廣播優先;

先接收的廣播接收者可以對廣播進行截斷,即后接收的廣播接收者將不再接收到此廣播;
先接收的廣播接收者可以對廣播進行修改,那么后接收的廣播接收者將接收到被修改后的廣播。
有序廣播的使用過程與普通廣播類似,只是在于廣播的發送方式不同:

sendOrderedBroadcast(intent);

App應用內廣播示例

Android中的廣播可以跨App直接通信(exported對于有intent-filter情況下默認值為true)。這種情況 可能帶來一些問題,如:
(1)其他App發出與當前App intent-filter相匹配的廣播,將導致當前App不斷接收廣播并處理;
(2)其他App注冊與當前App一致的intent-filter用于接收廣播,獲取廣播具體信息,而導致的安全性問題。

解決方案:
使用App應用內廣播(Local Broadcast),使得廣播的發送者和接收者都同屬于一個App。這樣可以提高App的安全性高和效率。

  • 方法1: 將全局廣播設置成局部廣播

    注冊廣播時將exported屬性設置為false,使得非本App內部發出的此廣播不被接收;

    在廣播發送和接收時,增設相應權限permission,用于權限驗證;

    發送廣播時指定該廣播接收器所在的包名,此廣播將只會發送到此包中的App內與之相匹配的有效廣播接收器中。通過intent.setPackage(packageName)指定包名。

  • 方法2:使用封裝好的LocalBroadcastManager類
    對于LocalBroadcastManager方式發送的應用內廣播,只能通過LocalBroadcastManager動態注冊,不能靜態注冊。
    注冊/注銷廣播接收器和發送廣播時將參數的context變成了LocalBroadcastManager的單一實例。示例如下:

public class MainActivity extends AppCompatActivity {private MyBroadcastReceiver myBroadcastReceiver;private LocalBroadcastManager localBroadcastManager;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 發廣播findViewById(R.id.me).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();intent.putExtra("name", "wongkyunban");// 對應BroadcastReceiver中intentFilter的actionintent.setAction("com.haha.haha.this.is.my.broadcast");// 發送廣播localBroadcastManager.sendBroadcast(intent);}});}// 注冊@Overrideprotected void onResume() {super.onResume();// 1. 實例化BroadcastReceiver子類和IntentFiltermyBroadcastReceiver = new MyBroadcastReceiver();IntentFilter intentFilter = new IntentFilter();// 實例化LocalBroadcastManager的實例localBroadcastManager = LocalBroadcastManager.getInstance(this);// 2. 設置接收廣播的類型,自定義一個廣播intentFilter.addAction("com.haha.haha.this.is.my.broadcast");// 3. 調用LocalBroadcastManager單一實例的registerReceiver()方法進行動態注冊localBroadcastManager.registerReceiver(myBroadcastReceiver, intentFilter);}// 注銷// 注冊廣播后,要在相應位置記得銷毀廣播// 即在onPause() 中unregisterReceiver(mBroadcastReceiver)// 當此Activity實例化時,會動態將MyBroadcastReceiver注冊到系統中// 當此Activity銷毀時,動態注冊的MyBroadcastReceiver將不再接收到相應的廣播。@Overrideprotected void onPause() {super.onPause();//銷毀在onResume()方法中的廣播//取消注冊應用內廣播接收器localBroadcastManager.unregisterReceiver(myBroadcastReceiver);} }

系統廣播示例

這個我們也是很常用的。
Android系統廣播action如下:

系統操作action
監聽網絡變化android.net.conn.CONNECTIVITY_CHANGE
關閉或打開飛行模式Intent.ACTION_AIRPLANE_MODE_CHANGED
充電時或電量發生變化Intent.ACTION_BATTERY_CHANGED
電池電量低Intent.ACTION_BATTERY_LOW
電池電量充足(即從電量低變化到飽滿時會發出廣播Intent.ACTION_BATTERY_OKAY
系統啟動完成后(僅廣播一次)Intent.ACTION_BOOT_COMPLETED
按下照相時的拍照按鍵(硬件按鍵)時Intent.ACTION_CAMERA_BUTTON
屏幕鎖屏Intent.ACTION_CLOSE_SYSTEM_DIALOGS
設備當前設置被改變時(界面語言、設備方向等)Intent.ACTION_CONFIGURATION_CHANGED
插入耳機時Intent.ACTION_HEADSET_PLUG
未正確移除SD卡但已取出來時(正確移除方法:設置–SD卡和設備內存–卸載SD卡)Intent.ACTION_MEDIA_BAD_REMOVAL
插入外部儲存裝置(如SD卡)Intent.ACTION_MEDIA_CHECKING
成功安裝APKIntent.ACTION_PACKAGE_ADDED
成功刪除APKIntent.ACTION_PACKAGE_REMOVED
重啟設備Intent.ACTION_REBOOT
屏幕被關閉Intent.ACTION_SCREEN_OFF
屏幕被打開Intent.ACTION_SCREEN_ON
關閉系統時Intent.ACTION_SHUTDOWN
重啟設備Intent.ACTION_REBOOT

關于廣播就寫這么多先啦。

謝謝閱讀。

總結

以上是生活随笔為你收集整理的Android四大组件之广播接收器BroadcastReceiver的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。