欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

android廣播的注冊,安卓注冊廣播方式有幾種

Android系統(tǒng)廣播(Broadcast)注冊,發(fā)送,接收流程解析

以下廣播簡稱Broadcast

成都創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供樂陵網站建設、樂陵做網站、樂陵網站設計、樂陵網站制作等企業(yè)網站建設、網頁設計與制作、樂陵企業(yè)網站模板建站服務,十年樂陵做網站經驗,不只是建網站,更提供有價值的思路和整體網絡服務。

?? 是Android四大組件之一,在四大組件的另外兩個組件 和 擁有發(fā)送和接收廣播的能力。Android 是在 進程間通信機制的基礎上實現(xiàn)的,內部基于消息發(fā)布和訂閱的事件驅動模型,廣播發(fā)送者負責發(fā)送消息,廣播接收者需要先訂閱消息,然后才能收到消息。 進程間通信與 的區(qū)別在于:

?? 有三種類型

?? 存在一個注冊中心,也可以說是一個調度中心,即 。廣播接收者將自己注冊到 中,并指定要接收的廣播類型;廣播發(fā)送者發(fā)送廣播時,發(fā)送的廣播首先會發(fā)送到 , 根據(jù)廣播的類型找到對應的 ,找到后邊將廣播發(fā)送給其處理。

?? 這里以普通廣播為例子, 接收者有兩種注冊方式,一種是 ,一種是 :

(廣播的發(fā)送分為 兩種,這里針對有序的廣播) 中的android:priority=""和 中的IntentFilter.setPriority(int)可以用來設置廣播接收者的優(yōu)先級,默認都是0 , 范圍是[-1000, 1000],值越大優(yōu)先級越高,優(yōu)先級越高越早收到。

?? 在相同優(yōu)先級接收同個類型廣播時, 的廣播接收器比 的廣播接收者更快的接收到對應的廣播,這個之后會進行分析。

?? 注:以下源碼基于rk3399_industry Android7.1.2

?? 的流程可分為 , 和 三個部分,這里依次分析下

?? 在Android系統(tǒng)的 機制中,前面提到, 作為一個注冊和調度中心負責注冊和轉發(fā) 。所以 的注冊過程就是把它注冊到 的過程。

?? 這里我們分析 廣播的過程, 和 有一個共同的父類 ,所以它們對應的注冊過程其實是調用 ,接下來我們按照流程逐步分析調用流程的源碼。

frameworks/base/core/java/android/content/ContextWrapper.java

?? 在之前的 Android應用程序啟動入口ActivityThread.main流程分析 分析過,在我們啟動 Activity 時會創(chuàng)建一個 對象,然后通過 傳給我們啟動的 ,其內部就會將該對象賦值給 ; 的 方法也是類似的賦值流程,這里放個簡易的源碼應該更好理解

?? 可以看到最后都會將生成的 對象賦值給對應的

對象。接下來繼續(xù)分析 , 即 函數(shù)。

/frameworks/base/core/java/android/app/ContextImpl.java

?? 這里我們首先看下如何將廣播接收者 封裝成一個 接口的 本地對象

/frameworks/base/core/java/android/app/LoadedApk.java

?? 每一個注冊過廣播接收者的 或 組件在font color='Crimson' LoadedApk /font類中都有個對應的 對象,該對象負責將 與 組件關聯(lián)起來。這些對象,以關聯(lián)的 作為關鍵字保存在一個 中。之后對應的 又以 的 作為關鍵字保存在 的成員變量 對象中。最后通過 對應的 方法獲得其 接口的 本地對象。之后再回到 注冊方法內,將 對象發(fā)給 進行注冊。

/frameworks/base/core/java/android/app/ActivityManagerNative.java

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

?? 在的 或 注冊一個 時,并不是將其注冊到font color='OrangeRed'AMS/font中,而是將與它關聯(lián)的font color='OrangeRed'InnerReceiver/font對象注冊到font color='OrangeRed'AMS/font中,當font color='OrangeRed'AMS/font接收到廣播時,會根據(jù) 在內部找到對應的font color='OrangeRed'InnerReceiver/font對象,然后在通過這個對象將這個廣播發(fā)送給對應的 處理。

?? 注冊過程這邊畫了一個簡單的流程圖:

?? font color='OrangeRed'Broadcast/font的發(fā)送過程可簡單描述為以下幾個過程:

frameworks/base/core/java/android/content/ContextWrapper.java

/frameworks/base/core/java/android/app/ContextImpl.java

/frameworks/base/core/java/android/app/ActivityManagerNative.java

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

android 注冊廣播有多少種方式

有兩種注冊廣播方式:

1.常駐型廣播

常駐型廣播,當應用程序關閉了,如果有廣播信息來,寫的廣播接收器同樣的能接收到,它的注冊方式就是在應用程序的AndroidManifast.xml 中進行注冊,這種注冊方式通常又被稱作靜態(tài)注冊。這種方式可以理解為通過清單文件注冊的廣播是交給操作系統(tǒng)去處理的。示例代碼如下:

AndroidManifest.xml中配置廣播

?xml version="1.0" encoding="utf-8"?

manifest xmlns:android=""

package="spl.broadCastReceiver"

android:versionCode="1"

android:versionName="1.0"

application android:icon="@drawable/icon" android:label="@string/app_name"

activity android:name=".BroadCastReceiverActivity"

android:label="@string/app_name"

intent-filter

action android:name="android.intent.action.MAIN" /

category android:name="android.intent.category.LAUNCHER" /

/intent-filter

/activity

!--廣播注冊、name里面填寫廣播類的路徑--

receiver android:name=".SmsBroadCastReceiver"

intent-filter android:priority="20"

action android:name="android.provider.Telephony.SMS_RECEIVED"/

/intent-filter

/receiver

/application

uses-sdk android:minSdkVersion="7" /

!-- 權限申請 --

uses-permission android:name="android.permission.RECEIVE_SMS"/uses-permission

/manifest

2.非常駐型廣播

非常駐型廣播,當應用程序結束了,廣播自然就沒有了,比如在 Activity 中的 onCreate 或者 onResume 中注冊廣播接收者,在 onDestory 中注銷廣播接收者。這樣廣播接收者就一個非常駐型的了,這種注冊方式也叫動態(tài)注冊。這種方式可以理解為通過代碼注冊的廣播是和注冊者關聯(lián)在一起的。比如寫一個監(jiān)聽 SDcard 狀態(tài)的廣播接收者:

package cn.sunzn.mosecurity.activity;

import android.app.Activity;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.Bundle;

import android.os.Environment;

public class SDcard extends Activity {

SdcardStateChanageReceiver sdcardStateReceiver;

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

sdcardStateReceiver = new SdcardStateChanageReceiver();

IntentFilter filter = new IntentFilter();

filter.addAction(Intent.ACTION_MEDIA_REMOVED);

filter.addAction(Intent.ACTION_MEDIA_EJECT);

filter.addAction(Intent.ACTION_MEDIA_MOUNTED);

filter.addDataScheme("file");

registerReceiver(sdcardStateReceiver, filter);

}

protected void onDestroy() {

unregisterReceiver(sdcardStateReceiver);

}

class SdcardStateChanageReceiver extends BroadcastReceiver {

public void onReceive(Context context, Intent intent) {

checkSDCard();

}

public void checkSDCard() {

String state = Environment.getExternalStorageState();

System.out.println(state);

if (state.equals(Environment.MEDIA_REMOVED) || state.equals(Environment.MEDIA_UNMOUNTED)) {

System.out.println("SDCard 已卸載!");

}

}

}

}

注冊廣播有幾種方式,這些方式有何優(yōu)缺點?請談談Android引入廣播機制的用意。

android中,不同進程之間傳遞信息要用到廣播,可以有兩種方式來實現(xiàn)。

第一種方式:在Manifest.xml中注冊廣播,是一種比較推薦的方法,因為它不需要手動注銷廣播(如果廣播未注銷,程序退出時可能會出錯)。

具體實現(xiàn)在Manifest的application中添加:上面兩個android:name分別是廣播名和廣播的動作(這里的動作是表示系統(tǒng)啟動完成),如果要自己發(fā)送一個廣播,在代碼中為:

Intent i = new Intent(“android.intent.action.BOOT_COMPLETED”);

sendBroadcast(i);

這樣,廣播就發(fā)出去了,然后是接收。

接收可以新建一個類,繼承至BroadcastReceiver,也可以建一個BroadcastReceiver的實例,然后得寫onReceive方法,實現(xiàn)如下:

protected BroadcastReceiver mEvtReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

if (action.equals(“android.intent.action.BOOT_COMPLETED”)) {

//Do something

}

}

};

第二種方式,直接在代碼中實現(xiàn),但需要手動注冊注銷,實現(xiàn)如下:

IntentFilter filter = new IntentFilter();

filter.addAction(“android.intent.action.BOOT_COMPLETED”);

registerReceiver(mEvtReceiver, filter); //這時注冊了一個recevier ,名為mEvtReceiver,然后同樣用上面的方法以重寫onReceiver,

最后在程序的onDestroy中要注銷廣播,實現(xiàn)如下:

@Override

public void onDestroy() {

super.onDestroy();

unregisterReceiver(mPlayerEvtReceiver);

}

22 AndroidBroadcast廣播機制

廣播(Broadcast)機制用于進程/線程間通信,廣播分為廣播發(fā)送和廣播接收兩個過程,其中廣播接收者BroadcastReceiver便是Android四大組件之一。

BroadcastReceiver分為兩類:

從廣播發(fā)送方式可分為三類:

廣播在系統(tǒng)中以BroadcastRecord對象來記錄, 該對象有幾個時間相關的成員變量.

廣播注冊,對于應用開發(fā)來說,往往是在Activity/Service中調用 registerReceiver() 方法,而Activity或Service都間接繼承于Context抽象類,真正干活是交給ContextImpl類。另外調用getOuterContext()可獲取最外層的調用者Activity或Service。

[ContextImpl.java]

其中broadcastPermission擁有廣播的權限控制,scheduler用于指定接收到廣播時onRecive執(zhí)行線程,當scheduler=null則默認代表在主線程中執(zhí)行,這也是最常見的用法

[ContextImpl.java]

ActivityManagerNative.getDefault()返回的是ActivityManagerProxy對象,簡稱AMP.

該方法中參數(shù)有mMainThread.getApplicationThread()返回的是ApplicationThread,這是Binder的Bn端,用于system_server進程與該進程的通信。

[- LoadedApk.java]

不妨令 以BroadcastReceiver(廣播接收者)為key,LoadedApk.ReceiverDispatcher(分發(fā)者)為value的ArrayMap 記為 A 。此處 mReceivers 是一個以 Context 為key,以 A 為value的ArrayMap。對于ReceiverDispatcher(廣播分發(fā)者),當不存在時則創(chuàng)建一個。

此處mActivityThread便是前面?zhèn)鬟f過來的當前主線程的Handler.

ReceiverDispatcher(廣播分發(fā)者)有一個內部類 InnerReceiver ,該類繼承于 IIntentReceiver.Stub 。顯然,這是一個Binder服務端,廣播分發(fā)者通過rd.getIIntentReceiver()可獲取該Binder服務端對象 InnerReceiver ,用于Binder IPC通信。

[- ActivityManagerNative.java]

這里有兩個Binder服務端對象 caller 和 receiver ,都代表執(zhí)行注冊廣播動作所在的進程. AMP通過Binder驅動將這些信息發(fā)送給system_server進程中的AMS對象,接下來進入AMS.registerReceiver。

[- ActivityManagerService.java]

其中 mRegisteredReceivers 記錄著所有已注冊的廣播,以receiver IBinder為key, ReceiverList為value為HashMap。

在BroadcastQueue中有兩個廣播隊列mParallelBroadcasts,mOrderedBroadcasts,數(shù)據(jù)類型都為ArrayListbroadcastrecord style="box-sizing: border-box;":/broadcastrecord

mLruProcesses數(shù)據(jù)類型為 ArrayListProcessRecord ,而ProcessRecord對象有一個IApplicationThread字段,根據(jù)該字段查找出滿足條件的ProcessRecord對象。

該方法用于匹配發(fā)起的Intent數(shù)據(jù)是否匹配成功,匹配項共有4項action, type, data, category,任何一項匹配不成功都會失敗。

broadcastQueueForIntent(Intent intent)通過判斷intent.getFlags()是否包含F(xiàn)LAG_RECEIVER_FOREGROUND 來決定是前臺或后臺廣播,進而返回相應的廣播隊列mFgBroadcastQueue或者mBgBroadcastQueue。

注冊廣播:

另外,當注冊的是Sticky廣播:

廣播注冊完, 另一個操作便是在廣播發(fā)送過程.

發(fā)送廣播是在Activity或Service中調用 sendBroadcast() 方法,而Activity或Service都間接繼承于Context抽象類,真正干活是交給ContextImpl類。

[ContextImpl.java]

[- ActivityManagerNative.java]

[- ActivityManagerService.java]

broadcastIntent()方法有兩個布爾參數(shù)serialized和sticky來共同決定是普通廣播,有序廣播,還是Sticky廣播,參數(shù)如下:

broadcastIntentLocked方法比較長,這里劃分為8個部分來分別說明。

這個過程最重要的工作是:

BroadcastReceiver還有其他flag,位于Intent.java常量:

主要功能:

這個過主要處于系統(tǒng)相關的10類廣播,這里不就展開講解了.

這個過程主要是將sticky廣播增加到list,并放入mStickyBroadcasts里面。

其他說明:

AMS.collectReceiverComponents :

廣播隊列中有一個成員變量 mParallelBroadcasts ,類型為ArrayListbroadcastrecord style="box-sizing: border-box;",記錄著所有的并行廣播。/broadcastrecord

動態(tài)注冊的registeredReceivers,全部合并都receivers,再統(tǒng)一按串行方式處理。

廣播隊列中有一個成員變量 mOrderedBroadcasts ,類型為ArrayListbroadcastrecord style="box-sizing: border-box;",記錄著所有的有序廣播。/broadcastrecord

發(fā)送廣播過程:

處理方式:

可見不管哪種廣播方式,都是通過broadcastQueueForIntent()來根據(jù)intent的flag來判斷前臺隊列或者后臺隊列,然后再調用對應廣播隊列的scheduleBroadcastsLocked方法來處理廣播;

在發(fā)送廣播過程中會執(zhí)行 scheduleBroadcastsLocked 方法來處理相關的廣播

[- BroadcastQueue.java]

在BroadcastQueue對象創(chuàng)建時,mHandler=new BroadcastHandler(handler.getLooper());那么此處交由mHandler的handleMessage來處理:

由此可見BroadcastHandler采用的是”ActivityManager”線程的Looper

[- BroadcastQueue.java]

此處mService為AMS,整個流程還是比較長的,全程持有AMS鎖,所以廣播效率低的情況下,直接會嚴重影響這個手機的性能與流暢度,這里應該考慮細化同步鎖的粒度。

android注冊廣播有幾種方式?

首先寫一個類要繼承BroadcastReceiver

第一種:在清單文件中聲明,添加

receive android:name=".IncomingSMSReceiver "

intent-filter

action android:name="android.provider.Telephony.SMS_RECEIVED")

intent-filter

receiver

第二種使用代碼進行注冊如:

IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");

IncomingSMSReceiver receiver = new IncomgSMSReceiver();

registerReceiver(receiver.filter);

Android動態(tài)廣播(Android8.0)

(a).動態(tài)注冊 ? ? ? ? ? ? 在UI中注冊的廣播,例如:

(b).靜態(tài)注冊 ? ? ? ? ? ??

需要在manifest中進行注冊(在安卓8.0后系統(tǒng)廢除了大部分靜態(tài)廣播,最好使用動態(tài)注冊)。

(a).系統(tǒng)廣播 ? ? ? ? ? ??

系統(tǒng)中已經定義的廣播,此類廣播只能由系統(tǒng)發(fā)出,并且需要在intent-filter中加上系統(tǒng)已經寫的action。? ? ? ? ? ? ?

(b).自定義廣播 ? ? ? ??

顧名思義,是用戶自己定義的廣播。

(a)我們首先需要一個廣播接收類 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

(b)其次注冊動態(tài)廣播

(c)最后需要通過send方法發(fā)送一個廣播供廣播接收者接受

另外還有有序廣播和無序廣播,這篇博客寫的比較詳細,供大家參考: Android的有序廣播和無序廣播(解決安卓8.0版本之后有序廣播的接收問題) - ming3 - 博客園 (cnblogs.com)

分享題目:android廣播的注冊,安卓注冊廣播方式有幾種
標題網址:http://chinadenli.net/article34/dssphpe.html

成都網站建設公司_創(chuàng)新互聯(lián),為您提供動態(tài)網站網站設計公司微信公眾號云服務器手機網站建設網站制作

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

營銷型網站建設