系列笔记11.2、观察者模式BroadcastReceiver

来源:互联网 发布:软件体系结构是什么 编辑:程序博客网 时间:2024/05/22 07:55


来看广播接收器掉基本原理。

    public class TestActivity extends Activity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        IntentFilter filter=new IntentFilter("info.update");
        registerReceiver(receiver,filter);
    }
    
    
    BroadcastReceiver receiver=new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            
        }
    };



先看注册过程,registerReceiver方法,它的实现是在Activity的父类ContextWrapper里

package android.content;
public class ContextWrapper extends Context {
    Context mBase;


    @Override
    public Intent registerReceiver(
        BroadcastReceiver receiver, IntentFilter filter) {
        return mBase.registerReceiver(receiver, filter);
    }




调用的mBase变量对应的类实现是ContextImpl,


class ContextImpl extends Context {
       @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) {
                    //获取Handler来投递消息
                    scheduler = mMainThread.getHandler(); 
                }
                //获取IIntentReceiver对象,用于与AMS交互,并通过Handler传递消息
                rd = new LoadedApk.ReceiverDispatcher(
                        receiver, context, scheduler, null, true).getIIntentReceiver();
            }
        }
        try {
            //调用ActivityManagerNative的registerReceiver
            return ActivityManagerNative.getDefault().registerReceiver(
                    mMainThread.getApplicationThread(), mBasePackageName,
                    rd, filter, broadcastPermission, userId);
        } catch (RemoteException e) {
            return null;
        }
    }


}


来看看mPackageInfo.getReceiverDispatcher(方法,mPackageInfo是一个LoadedApk对象。


package android.app;


public final class LoadedApk {

    private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
        = new ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>();

    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);
                }
            }
            if (rd == null) {

               //新建一个广播接收发布器ReceiverDispatcher对象
                rd = new ReceiverDispatcher(r, context, handler,
                        instrumentation, registered);
                if (registered) {
                    if (map == null) {
                        map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
                        mReceivers.put(context, map);
                    }
                    //存储BroadcastReceiver及广播接收发布器ReceiverDispatcher
                    map.put(r, rd);
                }
            } else {
                rd.validate(context, handler);
            }
            rd.mForgotten = false;
            return rd.getIIntentReceiver();
        }
    }


     static final class ReceiverDispatcher {

        final IIntentReceiver.Stub mIIntentReceiver;
        //构造函数的初始化
        ReceiverDispatcher(BroadcastReceiver receiver, Context context,
                Handler activityThread, Instrumentation instrumentation,
                boolean registered) {
            //mIIntentReceiver是一个Binder对象
            mIIntentReceiver = new InnerReceiver(this, !registered);
            mActivityThread = activityThread;
            ...
        }


        IIntentReceiver getIIntentReceiver() {
            return mIIntentReceiver;
        }


        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;
            }
        ...
        }
    }
 }


创建广播接收发布器ReceiverDispatcher时,会在构造函数创建InnerReceiver实例,这是个Binder对象。
ActivityManagerNative.getDefault().registerReceiver()方法会将该Binder对象传给AMS,以便接收广播。


回到ContextImpl的registerReceiverInternal方法,在获得了IIntentReceiver类型的Binder对象后,就开始把它注册到AMS中

package android.app;
public abstract class ActivityManagerNative extends Binder implements IActivityManager
{

 static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        //返回一个ActivityManagerProxy对象
        return new ActivityManagerProxy(obj);
    }

    static public IActivityManager getDefault() {
        return gDefault.get();
    }

    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        ...
        case REGISTER_RECEIVER_TRANSACTION://注册广播放处理,通过Binder驱动程序进入到AMS的registerReveiver中
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app =
                b != null ? ApplicationThreadNative.asInterface(b) : null;
            String packageName = data.readString();
            b = data.readStrongBinder();
            IIntentReceiver rec
                = b != null ? IIntentReceiver.Stub.asInterface(b) : null;
            IntentFilter filter = IntentFilter.CREATOR.createFromParcel(data);
            String perm = data.readString();
            int userId = data.readInt();
            Intent intent = registerReceiver(app, packageName, rec, filter, perm, userId);
            reply.writeNoException();
            if (intent != null) {
                reply.writeInt(1);
                intent.writeToParcel(reply, 0);
            } else {
                reply.writeInt(0);
            }
            return true;
        }
        ...
    }

    public IBinder asBinder() {
        return this;
    }

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            //调用asInterface初始化一个ActivityManagerProxy对象
            IActivityManager am = asInterface(b);          
            return am;
        }
    };


     class ActivityManagerProxy implements IActivityManager
     {
        public ActivityManagerProxy(IBinder remote)
        {
        mRemote = remote;
        }

        public IBinder asBinder(){
            return mRemote;
        }

        private IBinder mRemote;

        public Intent registerReceiver(IApplicationThread caller, String packageName,
            IIntentReceiver receiver,
            IntentFilter filter, String perm, int userId) throws RemoteException
            {
              Parcel data = Parcel.obtain();
            Parcel reply = Parcel.obtain();
            data.writeInterfaceToken(IActivityManager.descriptor);
            data.writeStrongBinder(caller != null ? caller.asBinder() : null);
            data.writeString(packageName);

            //注册IIntentReceiver类型的Binder对象到AMS
            data.writeStrongBinder(receiver != null ? receiver.asBinder() : null);
            filter.writeToParcel(data, 0);
            data.writeString(perm);
            data.writeInt(userId);
            // 向AMS提交注册广播接收器的请求
            mRemote.transact(REGISTER_RECEIVER_TRANSACTION, data, reply, 0);
            reply.readException();
            Intent intent = null;
            int haveIntent = reply.readInt();
            if (haveIntent != 0) {
                intent = Intent.CREATOR.createFromParcel(reply);
            }
            reply.recycle();
            data.recycle();
            return intent;
            }
     }
  
}
 


这个函数通过Binder驱动程序就进入到AMS的registerReceiver方法中去了。


package com.android.server.am;


public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {


    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
        enforceNotIsolatedCaller("registerReceiver");
        int callingUid;
        int callingPid;
        synchronized(this) {
            //1. 获取 ProcessRecord
            ProcessRecord callerApp = null;
            if (caller != null) {
                callerApp = getRecordForAppLocked(caller);
                if (callerApp == null) {
                    ...
                }
                
            } 
            ...


            List allSticky = null;


            // 2.根据Action查找匹配的sticky接收器
            Iterator actions = filter.actionsIterator();
            if (actions != null) {
                while (actions.hasNext()) {
                    String action = (String)actions.next();
                    allSticky = getStickiesLocked(action, filter, allSticky,
                            UserHandle.USER_ALL);
                    allSticky = getStickiesLocked(action, filter, allSticky,
                            UserHandle.getUserId(callingUid));
                }
            } else {
                ...
            }


            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;


          
            if (receiver == null) {
                return sticky;
            }
            // 3.获取ReceiverList
            ReceiverList rl
                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
            if (rl == null) {
                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
                        userId, receiver);
                if (rl.app != null) {
                    rl.app.receivers.add(rl);
                } else {
                    try {
                        receiver.asBinder().linkToDeath(rl, 0);
                    } catch (RemoteException e) {
                        return sticky;
                    }
                    rl.linkedToDeath = true;
                }
                mRegisteredReceivers.put(receiver.asBinder(), rl);
                ...
            }
            //4.构建BroadcastFilter对象
            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
                    permission, callingUid, userId);
            rl.add(bf);
            ...
            mReceiverResolver.addFilter(bf);
            ...


            return sticky;
        }
    }

\




广播的发送过程也是以AMS为中心。
通过sendBroadcast把一个广播通过Binder发送给AMS,AMS根据这个广播的Action类型找到相应的广播接收器,然后将这个广播放进自己的消息队列中




package com.android.server.am;


public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {


 private final int broadcastIntentLocked(ProcessRecord callerApp,
            String callerPackage, Intent intent, String resolvedType,
            IIntentReceiver resultTo, int resultCode, String resultData,
            Bundle map, String requiredPermission, int appOp,
            boolean ordered, boolean sticky, int callingPid, int callingUid,
            int userId) {
        intent = new Intent(intent);
        ...
        List receivers = null;
        List<BroadcastFilter> registeredReceivers = null;
        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
                 == 0) {
            receivers = collectReceiverComponents(intent, resolvedType, users);
        }
        if (intent.getComponent() == null) {
            //查询到该Intent对应的BroadcastFilter,也就是接收器列表
            registeredReceivers = mReceiverResolver.queryIntent(intent,
                    resolvedType, false, userId);
        }
        ...
        boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 
            if (!replaced) {
                queue.enqueueOrderedBroadcastLocked(r);
                //处理广播的异步分发
                queue.scheduleBroadcastsLocked();
            }
        }


        return ActivityManager.BROADCAST_SUCCESS;
    }








消息循环中处理这个广播,并通过Binder机制把这个广播分发给注册的ReceiverDispatcher
package com.android.server.am;   
public final class BroadcastQueue {
    public void scheduleBroadcastsLocked() {
        ...
        if (mBroadcastsScheduled) {
            return;
        }
        mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
        mBroadcastsScheduled = true;
    }




    final Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case BROADCAST_INTENT_MSG: {
                    if (DEBUG_BROADCAST) Slog.v(
                            TAG, "Received BROADCAST_INTENT_MSG");
                    //处理下一个广播
                    processNextBroadcast(true);
                } break;
    }


    final void processNextBroadcast(boolean fromMsg) {
        synchronized(mService) {
           ...
           performReceiveLocked(r.callerApp, r.resultTo,
                                new Intent(r.intent), r.resultCode,
                                r.resultData, r.resultExtras, false, false, r.userId);
    }              




    private static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
            Intent intent, int resultCode, String data, Bundle extras,
            boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
        // Send the intent to the receiver asynchronously using one-way binder calls.
        if (app != null && app.thread != null) {
            app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
                    data, extras, ordered, sticky, sendingUser, app.repProcState);
        } else {
            receiver.performReceive(intent, resultCode, data, extras, ordered,
                    sticky, sendingUser);
        }
    }




}








ReceiverDispatcher的内部类Args在Activity所在的线程消息循环中处理这个广播,最终是将这个广播分发给所注册的BroadcastReceiver实例的onReceive函数进行处理




public final class LoadedApk {
      static final class ReceiverDispatcher {
          static final class ReceiverDispatcher {


          public void performReceive(Intent intent, int resultCode, String data,
                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
            if (ActivityThread.DEBUG_BROADCAST) {
                int seq = intent.getIntExtra("seq", -1);
                Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction() + " seq=" + seq
                        + " to " + mReceiver);
            }
            Args args = new Args(intent, resultCode, data, extras, ordered,
                    sticky, sendingUser);
            //执行Runnable
            if (!mActivityThread.post(args)) {
                if (mRegistered && ordered) {
                    IActivityManager mgr = ActivityManagerNative.getDefault();
                    if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                            "Finishing sync broadcast to " + mReceiver);
                    args.sendFinished(mgr);
                  }
              }
           }




         }
              final class Args extends BroadcastReceiver.PendingResult implements Runnable {
    
                public void run() {
                ...
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
                try {
                    ClassLoader cl =  mReceiver.getClass().getClassLoader();
                    intent.setExtrasClassLoader(cl);
                    setExtrasClassLoader(cl);
                    receiver.setPendingResult(this);
                    receiver.onReceive(mContext, intent);
                } catch (Exception e) {
                ...




            }






























































0 0