Android四大元件BroadcastReceiver原始碼分析
1 用法
(1)定義廣播接收者
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//TODO
}
}
(2)註冊廣播
1 靜態註冊
<receiver android:name=".MyBroadcastReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
2 動態註冊
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BROADCAST_ACTION);
registerReceiver(mBroadcastReceiver, intentFilter);
(3)傳送廣播
Intent intent = new Intent();
intent.setAction(BROADCAST_ACTION);
intent.putExtra("name", "qqyumidi");
sendBroadcast(intent);
2 原始碼分析
1 ContextWrapper
@Override
public Intent registerReceiver(
BroadcastReceiver receiver, IntentFilter filter) {
return mBase.registerReceiver(receiver, filter);
}
mBase是contextImpl,說過無數次了。2 ContextImpl
@Override public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) { return registerReceiverInternal(receiver, getUserId(), filter, broadcastPermission, scheduler, getOuterContext()); }
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context) {
IIntentReceiver rd = null;
if (receiver != null) {
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = new LoadedApk.ReceiverDispatcher(
receiver, context, scheduler, null, true).getIIntentReceiver();
}
}
try {
return ActivityManagerNative.getDefault().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName,
rd, filter, broadcastPermission, userId);
} catch (RemoteException e) {
return null;
}
}
因為註冊廣播是一個程序間通訊的過程,所以不能直接只用BroadcastReceiver。mPackageInfo.getReceiverDispatcher將broadcast轉化為一個binder,這個過程和service的
mPackageInfo.getServiceDispatcher型別。mPackageInfo是LoadedApk例項,下面看看getReceiverDispatcher
3 LoadedApk
public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
Context context, Handler handler,
Instrumentation instrumentation, boolean registered) {
synchronized (mReceivers) {
LoadedApk.ReceiverDispatcher rd = null;
ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
if (registered) {
map = mReceivers.get(context);
if (map != null) {
rd = map.get(r);
}
}
......
rd = new ReceiverDispatcher(r, context, handler,
instrumentation, registered);
......
return rd.getIIntentReceiver();
}
}
這裡涉及到LoadedApk,ReceiverDispatcher,
private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
= new ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>();
rd是一個ReceiverDispatcher例項,他呼叫了自己的getIIntentReceiver方法
IIntentReceiver getIIntentReceiver() {
return mIIntentReceiver;
}
mIIntentReceiver是一個binder,下面就來看看怎麼把broadcastReceiver轉化為binder的4 ReceiverDispatcher
ReceiverDispatcher(BroadcastReceiver receiver, Context context,
Handler activityThread, Instrumentation instrumentation,
boolean registered) {
if (activityThread == null) {
throw new NullPointerException("Handler must not be null");
}
mIIntentReceiver = new InnerReceiver(this, !registered);
mReceiver = receiver;
mContext = context;
mActivityThread = activityThread;
mInstrumentation = instrumentation;
mRegistered = registered;
mLocation = new IntentReceiverLeaked(null);
mLocation.fillInStackTrace();
}
ReceiverDispatcher例項化時建立了InnerReceiver,InnerReceiver就是一個binder,這裡就將broadcastReceiver“轉化“為binder了,其實這個過程和service轉化為binder一模一樣,可以結合service來比較。
5 InnerReceiver
final static class InnerReceiver extends IIntentReceiver.Stub {
final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
final LoadedApk.ReceiverDispatcher mStrongRef;
InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
mStrongRef = strong ? rd : null;
}
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
......
}
}
6 ActivityManagerProxy(ActivityManager內部類)
回到第2步,接著執行了ActivityManagerNative.getDefault().registerReceiver,什麼不用說了,大家都懂,直接上程式碼。
相關推薦
Android四大元件BroadcastReceiver原始碼分析
1 用法 (1)定義廣播接收者 public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context
Android四大元件——BroadcastReceiver(原理篇)
前言 Android四大元件——BroadcastReceiver(基礎篇)裡面介紹了BroadcastReceiver相關的基礎知識,本文將從Android 8.0原始碼來分析一下廣播的註冊和接收原理。 BroadcastReceiver的註冊 Android系統中Broa
Android四大元件—BroadcastReceiver
package com.example.administrator.broadcastreceiveractivity; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle;
Android--四大元件之BroadCastReceiver(生命週期、實現原理及使用等)
####1. BroadCastReceiver是什麼? ####2. 廣播型別 ######1). 有序廣播 ######2). 無序廣播 ####3. 生命週期 ####4. 實現原理 ####5. 使用方法 ####6. 許可權問題(安全性) ####7. LocalBroad
android四大元件(3)(BroadcastReceiver)
一、aandroid的四大元件BroadcastReceiver廣播接收器(用於接收程式所發出的Broadcast Intent),其本生就是一個全域性的監聽器,用於監聽系統全域性的廣播訊息。由於BroadcastReceiver是全域性的監聽器,所以它可以非常方便地實現系統中不同元件之間地通訊。
Android四大元件之BroadcastReceiver應用詳解
今天我們來講一下Android中BroadcastReceiver的相關知識。 BroadcastReceiver也就是“廣播接收者”的意思,顧名思義,它就是用來接收來自系統和應用中的廣播。 在Android系統中,廣播體現在方方面面,例如當開機完成後系統會產生一條廣播,接收到這條廣播就能實
Android 四大元件之“ BroadcastReceiver ”
前言 Android四大元件重要性已經不言而喻了,今天談談的是Android中的廣播機制。在我們上學的時候,每個班級的教室裡都會裝有一個喇叭,這些喇叭都是接入到學校的廣播室的,一旦有什麼重要的通知,就會播放一條廣播來告知全校的師生。類似的工作機制其實在計算機領域也有很廣泛的應用,如果你瞭解網路通訊原理應該會知
Android四大元件應用系列——使用BroadcastReceiver和Service實現倒計時
public class ClockActivity extends Activity { private TextView tvClock; public static final String CLOCK_ACTION="com.jereh.Clock_Action";
Android四大元件之BroadcastReceiver
1. 概述 BroadcastReceiver,中文翻譯為“廣播接收器“,要了解廣播接收器的定義,先介紹一下Broadcast(廣播)的含義: Broadcast:廣播 它是實現不同(應用)程式或者是同一個應用程式內部進行訊息傳遞的一種機制,它的功能定義
Android四大元件之BroadcastReceiver(下)
(一)概述 上節我們對BroadcastReceiver已經有了一個初步的瞭解了,知道兩種廣播型別:標準與有序, 動態或靜態註冊廣播接收者,監聽系統廣播,自己傳送廣播!已經滿足我們的基本需求了~ 但是前面寫的廣播都是全域性廣播!這同樣意味著我們APP發出的廣播
Android四大元件之廣播接收者(BroadcastReceiver)
廣播接收者簡介: 為了監聽來自系統或應用程式的廣播事件,Android系統提供了BroadcastReceiver(廣播接收者)元件。 廣播接收者建立: 右擊—-包名—-new—-Other—-Broadcast Receiver—-名字自取、其他預設
Android四大元件之BroadcastReceiver(廣播)
什麼是廣播 廣播是一個全域性的監聽器,屬於Android四大元件之一,它分為兩個角色:廣播發送者、廣播接收者 廣播用於不同元件之間(應用內/不同應用之間),還有多執行緒之間的通訊 - 廣播的
android四大元件啟動流程-BroadcastReceiver啟動流程(基於android 6.0)
廣播在android系統中,使用非常頻繁,可以說是耦合度極低的一種通訊方式。作業系統一方面為了讓任務執行互不干擾,即使某個任務掛了,也不會影響其他的任務,因此才有了程序,但是任務之間通常又是相關的,又需要涉及到程序間的通訊,當然程序間通訊的方式有很多種,管道、訊號、訊息佇
Android四大元件之BroadcastReceiver工作原理
1.廣播的註冊 As we all know,廣播的註冊也是分兩種:動態註冊和靜態註冊,前者是在Activity生命週期中用java程式碼註冊和解除註冊,後者是在AndroidManifest檔案中。後者在安裝時由PKMS解析並註冊的,後續會單獨分析,這裡只分析廣播的動態註
Android四大元件之BroadcastReceiver的使用
工作之餘,有些閒功夫,想想還是總結一下基礎知識,Android廣播在專案中使用還是比較多的,相對於四大元件,可能僅次於Activity的使用。首先,我們得知道廣播的作用:從字面意思上來看,廣播就好比收音機通知收聽者,同時也能攜帶廣播資訊。廣播的種類可分為有序廣播和無需廣播,
Android四大元件:BroadcastReceiver
4.3 廣播發送者向AMS傳送廣播 4.3.1 廣播的傳送 廣播是用”意圖(Intent)“標識定義廣播的本質:定義廣播所具備的“意圖(Intent)”廣播發送:廣播發送者將此廣播的”意圖“通過sendBroadcast()方法傳送出去4.3.2 廣播的型別 廣播的型別主要分為5類: 普通廣播(Normal
Android IntentService用法和原始碼分析
關於IntentService的介紹,我個人覺得還是先看官方描述比較好: IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) o
《瞭解Android四大元件 》的補充
Activity View元件是所有UI控制元件、容器控制元件的基類,View元件就是Android應用中使用者實實在在看到的部分。但View元件需要放到容器元件中,或者使用Activity將它顯示出來。如果需要通過某個Activity把指定的View顯示出來,呼叫Activit
瞭解Android四大元件
Activity 用途:Activity是一個應用程式元件,其所有操作都與使用者密切相關,它提供一個螢幕,在此進行使用者互動從而完成某項任務。(是使用者操作的視覺化介面;它為使用者提供了一個完成操作指令的視窗)在一個android應用中,一個Activity通常就是一個單獨的螢幕,它上面
Android 四大元件中 android:exported 屬性詳解
當我們在用360等檢測軟體掃描應用漏洞時,掃描結果可能歸類為安全漏洞,涉及一個Android:exported屬性,這個屬性究竟是用來幹嘛的呢,詳情見下圖: 因此,查了官方API,學習了一下這個屬性! android:exported 是Android中的四大元件 Ac