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,什么不用说了,大家都懂,直接上代码。

    原文作者:胡育诚
    原文地址: https://blog.csdn.net/u011617742/article/details/53411806
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞