1. 程式人生 > >Android四大元件BroadcastReceiver原始碼分析

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