当前位置: 首页 > news >正文

网站左悬浮代码网站前期推广

网站左悬浮代码,网站前期推广,那个网站做图片,业之峰之前看过 Activity 的启动过程,也看过 Service 启动过程,今天又重新对广播的发送和接收过程做一个源码的了解和查看。 1. registerReceiver MyBroadcastReceiver mBroadcastReceiver new MyBroadcastReceiver();IntentFilter filter new IntentFilter…

之前看过 Activity 的启动过程,也看过 Service 启动过程,今天又重新对广播的发送和接收过程做一个源码的了解和查看。

1. registerReceiver

        MyBroadcastReceiver mBroadcastReceiver  = new MyBroadcastReceiver();IntentFilter filter = new IntentFilter();filter.addAction("com.example.qq");registerReceiver(mBroadcastReceiver, filter);

我们通常会自定义一个类 MyBroadcastReceiver extends BroadcastReceiver.

跟随 registerReceiver 我们走到第二个步骤:

1.1 ContextImpl#registerReceiver

@Overridepublic Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {return registerReceiver(receiver, filter, null, null);}@Overridepublic Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,String broadcastPermission, Handler scheduler) {return registerReceiverInternal(receiver, getUserId(),filter, broadcastPermission, scheduler, getOuterContext());}

最终会执行到 registerReceiverInternal() 这个方法,紧接着到第三个步骤:

1.2. ContextImpl#registerReceiverInternal

private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,IntentFilter filter, String broadcastPermission,Handler scheduler, Context context) {IIntentReceiver rd = null;//这个IItentReceiver 是一个aidl ,一个Binderif (receiver != null) {if (mPackageInfo != null && context != null) {//这个为null, 因为前面我们传的是null,获取主线程的一个handlerif (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 {//这里我们仔细查看,这里对比我们平时写的Aidlfinal Intent intent = ActivityManagerNative.getDefault().registerReceiver(mMainThread.getApplicationThread(), mBasePackageName,rd, filter, broadcastPermission, userId);if (intent != null) {intent.setExtrasClassLoader(getClassLoader());intent.prepareToEnterProcess();}return intent;} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}

对于 :

final Intent intent = ActivityManagerNative.getDefault().registerReceiver(mMainThread.getApplicationThread(), mBasePackageName,rd, filter, broadcastPermission, userId);

ActivityManagerNative.getDefault() 获取到一个 IActivityManager 对象,此时我发现,我进入一个类名为:
ActivityManagerNative 的一个类中。

这里补充 IActivityManager ,它是一个 aidl 文件,如下:

public interface IActivityManager extends IInterface {....
}

这时让我想起我们以前写 aidl 的示例时,系统自动帮我们生成的文件,下面我们来对比一下,可以加深对 aidl 的理解:

自动生成的aidl文件
我们创建一个 IMyAidl.aidl 文件,编译系统会自动生成大致如下:

public interface IMyAidl extends android.os.IInterface{public static abstract class Stub extends android.os.Binder implements xx.IMyAidl{public Stub(){this.attachInterface(this, DESCRIPTOR);}public static com.example.service.bean.IMyAidl asInterface(android.os.IBinder obj) {xxx...return new com.example.service.bean.IMyAidl.Stub.Proxy(obj);}@Overridepublic boolean onTransact(int code, android.os.Parcel data, android.os.Parcel            reply, int flags) throws android.os.RemoteException {case TRANSACTION_addPerson: {//其中一个方法data.enforceInterface(DESCRIPTOR);com.example.service.bean.Person _arg0;if ((0 != data.readInt())) {_arg0 = com.example.service.bean.Person.CREATOR.createFromParcel(data);} else {_arg0 = null;}this.addPerson(_arg0);reply.writeNoException();return true;}}}private static class Proxy implements xx.IMyAidl {private android.os.IBinder mRemote;Proxy(android.os.IBinder remote) {mRemote = remote;}@Overridepublic void addPerson(com.example.service.bean.Person person) throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);if ((person != null)) {_data.writeInt(1);person.writeToParcel(_data, 0);} else {_data.writeInt(0);}//调用远程binder,transactmRemote.transact(Stub.TRANSACTION_addPerson, _data, _reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}}static final int TRANSACTION_addPerson = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}

其中我们最主要关心的是 StubProxy .那么类比下 ActivityManagerNative 类(我简化了一下):

public abstract class ActivityManagerNative extends Binder implements IActivityManager{class ActivityManagerProxy implements IActivityManager{public ActivityManagerProxy(IBinder remote) {mRemote = remote;}}
}

你会发现这与系统帮我们自动生成文件的结构有异曲同工之处,那么在这里:

ActivityManagerNative ------ 对应的就是 Stub

ActivityManagerProxy ------- 对应的就是 Proxy

那么真正实现 ActivityManagerNative 又是谁呢,其实就是 ActivityManagerService , 可看到:

public final class ActivityManagerService extends ActivityManagerNative ...{...
}

这样的话,我们回到之前的那个步骤:

final Intent intent = ActivityManagerNative.getDefault().registerReceiver(mMainThread.getApplicationThread(), mBasePackageName,rd, filter, broadcastPermission, userId);

这里我们就知道了 这里调用 ActivityManagerNative.getDefault().registerReceiver 其实就是调用 ActivityManagerService.registerReceiver() 方法。

还有一个补充的是 mMainThread.getApplicationThread() 实际上对应的是 ApplicationThread

1.3 ActivityManagerService#registerReceiver

这个方法有点长,不过没关系,分块看就行:

public Intent registerReceiver(IApplicationThread caller, String callerPackage,IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {enforceNotIsolatedCaller("registerReceiver");ArrayList<Intent> stickyIntents = null;ProcessRecord callerApp = null;int callingUid;int callingPid;synchronized(this) {//这个肯定不为nullif (caller != null) {//表示启动app的进程信息保存在ProcessRecord类型的对象中callerApp = getRecordForAppLocked(caller);if (callerApp == null) {throw new SecurityException("Unable to find app for caller " + caller+ " (pid=" + Binder.getCallingPid()+ ") when registering receiver " + receiver);}....} else {...}userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,ALLOW_FULL_ONLY, "registerReceiver", callerPackage);....  // Collect stickies of usersint[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };//遍历 action while (actions.hasNext()) {String action = actions.next();for (int id : userIds) {ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);if (stickies != null) {ArrayList<Intent> intents = stickies.get(action);if (intents != null) {if (stickyIntents == null) {stickyIntents = new ArrayList<Intent>();}stickyIntents.addAll(intents);}}}}}ArrayList<Intent> allSticky = null;if (stickyIntents != null) {final ContentResolver resolver = mContext.getContentResolver();// Look for any matching sticky broadcasts...for (int i = 0, N = stickyIntents.size(); i < N; i++) {Intent intent = stickyIntents.get(i);// If intent has scheme "content", it will need to acccess// provider that needs to lock mProviderMap in ActivityThread// and also it may need to wait application response, so we// cannot lock ActivityManagerService here.if (filter.match(resolver, intent, true, TAG) >= 0) {if (allSticky == null) {allSticky = new ArrayList<Intent>();}allSticky.add(intent);}}}// The first sticky in the list is returned directly back to the client.Intent sticky = allSticky != null ? allSticky.get(0) : null;if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);if (receiver == null) {return sticky;}synchronized (this) {...//获取接收者的一个集合 ReceiverListReceiverList rl = 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);} ...//IntentFilter 相关的BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,permission, callingUid, userId);rl.add(bf);if (!bf.debugCheck()) {Slog.w(TAG, "==> For Dynamic broadcast");}//最后添加到了mReceiverResolver 中,最后发送广播也是从这里面去取///**//* Keeps track of all IIntentReceivers that have been registered for broadcasts.// * Hash keys are the receiver IBinder, hash value is a ReceiverList.//*///final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();mReceiverResolver.addFilter(bf);// Enqueue broadcasts for all existing stickies that match// this filter.if (allSticky != null) {ArrayList receivers = new ArrayList();receivers.add(bf);final int stickyCount = allSticky.size();for (int i = 0; i < stickyCount; i++) {Intent intent = allSticky.get(i);//得到一个接收此广播的队列 BroadcastQueueBroadcastQueue queue = broadcastQueueForIntent(intent);//广播的信息封装在一个BroadcastRecord 对象中BroadcastRecord r = new BroadcastRecord(queue, intent, null,null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,null, 0, null, null, false, true, true, -1);// 这里可以认为是一个入队操作,就像Handler 中的 Message中一样        queue.enqueueParallelBroadcastLocked(r);//调用 scheduleBroadcastsLockedqueue. scheduleBroadcastsLocked();}}return sticky;}}

2. sendBoradcastReceiver

        Intent intent = new Intent();intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.setAction("com.example.qq");sendBroadcast(intent);

2.1 ContextImpl#sendBroadcast

@Overridepublic void sendBroadcast(Intent intent) {warnIfCallingFromSystemProcess();String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());try {intent.prepareToLeaveProcess(this);ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(), intent, resolvedType, null,Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,getUserId());} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}

这里我们就知道 ActivityManagerNative.getDefault() 实际上可以认为是 ActivityManagerService ,调用 broadcastIntent 方法。

2.2 ActivityManagerService#broadcastIntent

 public final int broadcastIntent(IApplicationThread caller,Intent intent, String resolvedType, IIntentReceiver resultTo,int resultCode, String resultData, Bundle resultExtras,String[] requiredPermissions, int appOp, Bundle bOptions,boolean serialized, boolean sticky, int userId) {enforceNotIsolatedCaller("broadcastIntent");synchronized(this) {intent = verifyBroadcastLocked(intent);final ProcessRecord callerApp = getRecordForAppLocked(caller);final int callingPid = Binder.getCallingPid();final int callingUid = Binder.getCallingUid();final long origId = Binder.clearCallingIdentity();//到这里int res = broadcastIntentLocked(callerApp,callerApp != null ? callerApp.info.packageName : null,intent, resolvedType, resultTo, resultCode, resultData, resultExtras,requiredPermissions, appOp, bOptions, serialized, sticky,callingPid, callingUid, userId);Binder.restoreCallingIdentity(origId);return res;}}

2.3 ActivityManagerService#broadcastIntentLocked

这个里面方法挺长的

....
BroadcastQueue queue = broadcastQueueForIntent(intent);BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,callerPackage, callingPid, callingUid, resolvedType,requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,resultData, resultExtras, ordered, sticky, false, userId);if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r+ ": prev had " + queue.mOrderedBroadcasts.size());if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,"Enqueueing broadcast " + r.intent.getAction());boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);if (!replaced) {queue.enqueueOrderedBroadcastLocked(r);queue.scheduleBroadcastsLocked();}....

2.4 BroadcastQueue#scheduleBroadcastsLocked

public void scheduleBroadcastsLocked() {if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["+ mQueueName + "]: current="+ mBroadcastsScheduled);if (mBroadcastsScheduled) {return;}//这里发送了一条消息mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));mBroadcastsScheduled = true;}private final class BroadcastHandler extends Handler {public BroadcastHandler(Looper looper) {super(looper, null, true);}@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case BROADCAST_INTENT_MSG: {if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Received BROADCAST_INTENT_MSG");processNextBroadcast(true);} break;...

2.5 BroadcastQueue#processNextBroadcast

这个方法也比较长,挑一些重点的看下:

final void processNextBroadcast(boolean fromMsg) {...// First, deliver any non-serialized broadcasts right away.//这个表示对无序广播的处理while (mParallelBroadcasts.size() > 0) {r = mParallelBroadcasts.remove(0);r.dispatchTime = SystemClock.uptimeMillis();r.dispatchClockTime = System.currentTimeMillis();final int N = r.receivers.size();if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["+ mQueueName + "] " + r);for (int i=0; i<N; i++) {//取出一个接收者targetObject target = r.receivers.get(i);if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,"Delivering non-ordered on [" + mQueueName + "] to registered "+ target + ": " + r);//又调用   deliverToRegisteredReceiverLocked      deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);}addBroadcastToHistoryLocked(r);if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["+ mQueueName + "] " + r);}
}

2.6 BroadcastQueue#deliverToRegisteredReceiverLocked

 private void deliverToRegisteredReceiverLocked(BroadcastRecord r,BroadcastFilter filter, boolean ordered, int index) {//根据上面所传的ordered 为false 表示无序广播....if (ordered) {//这个表示有序广播r.receiver = filter.receiverList.receiver.asBinder();r.curFilter = filter;filter.receiverList.curBroadcast = r;r.state = BroadcastRecord.CALL_IN_RECEIVE;if (filter.receiverList.app != null) {// Bump hosting application to no longer be in background// scheduling class.  Note that we can't do that if there// isn't an app...  but we can only be in that case for// things that directly call the IActivityManager API, which// are already core system stuff so don't matter for this.r.curApp = filter.receiverList.app;filter.receiverList.app.curReceiver = r;mService.updateOomAdjLocked(r.curApp);}}try {//关于isFullBackup  Process is currently hosting a backup agent for backup or restore//public boolean inFullBackup;默认是falseif (filter.receiverList.app != null && filter.receiverList.app.inFullBackup) {// Skip delivery if full backup in progress// If it's an ordered broadcast, we need to continue to the next receiver.if (ordered) {skipReceiverLocked(r);}} else {//到这里performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,new Intent(r.intent), r.resultCode, r.resultData,r.resultExtras, r.ordered, r.initialSticky, r.userId);}if (ordered) {r.state = BroadcastRecord.CALL_DONE_RECEIVE;}} catch (RemoteException e) {....}

2.7 BroadcastQueue#performReceiveLocked

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) {if (app.thread != null) {app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,data, extras, ordered, sticky, sendingUser, app.repProcState);}....    }

app.threadApplicationThread , 此时回归到了客户端进程,ApplicationThread 中了

2.8 ApplicationThread#scheduleRegisteredReceiver

public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,int resultCode, String dataStr, Bundle extras, boolean ordered,boolean sticky, int sendingUser, int processState) throws RemoteException {updateProcessState(processState, false);receiver.performReceive(intent, resultCode, dataStr, extras, ordered,sticky, sendingUser);}

这里调用了 IIntentReceiver#performReceive 方法, 其中 IIntentReceiver 是一个 aidl ,如下:
/framworkds/base/core/java/android/content/IIntentReceiver.aidl

/*** System private API for dispatching intent broadcasts.  This is given to the* activity manager as part of registering for an intent broadcasts, and is* called when it receives intents.** {@hide}*/
oneway interface IIntentReceiver {void performReceive(in Intent intent, int resultCode,String data, in Bundle extras, boolean ordered, boolean sticky);
}

既然是 aidl 肯定有最终实现者,全局搜索发现:

InnerReceiver 是最终实现者,是ReceiverDispatcher 的一个静态内部类,在 LoadedApk.java 文件中

LoadedApk#ReceiverDispatcher

static final class ReceiverDispatcher {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;}//这里是最终执行的方法 performReceive@Overridepublic void performReceive(Intent intent, int resultCode, String data,Bundle extras, boolean ordered, boolean sticky, int sendingUser) {final LoadedApk.ReceiverDispatcher rd;if (intent == null) {Log.wtf(TAG, "Null intent received");rd = null;} else {rd = mDispatcher.get();}...if (rd != null) {//不为null  执行到这里 rd.performReceive(intent, resultCode, data, extras,ordered, sticky, sendingUser);} else {// The activity manager dispatched a broadcast to a registered// receiver in this process, but before it could be delivered the// receiver was unregistered.  Acknowledge the broadcast on its// behalf so that the system's broadcast sequence can continue.if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,"Finishing broadcast to unregistered receiver");IActivityManager mgr = ActivityManagerNative.getDefault();try {if (extras != null) {extras.setAllowFds(false);}mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}}}

2.9 ReceiverDispatcher#performReceive

public void performReceive(Intent intent, int resultCode, String data,Bundle extras, boolean ordered, boolean sticky, int sendingUser) {//将信息封装到Args 中final Args args = new Args(intent, resultCode, data, extras, ordered,sticky, sendingUser);if (intent == null) {Log.wtf(TAG, "Null intent received");} else {if (ActivityThread.DEBUG_BROADCAST) {int seq = intent.getIntExtra("seq", -1);Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()+ " seq=" + seq + " to " + mReceiver);}}//这里 IActivityThread 一个Handler 类型。post了一条runnable,if (intent == null || !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);}}}

这里补充下 : mActivityThread 赋值是在构造方法中赋值的:

ReceiverDispatcher(BroadcastReceiver receiver, Context context,Handler activityThread, Instrumentation instrumentation,boolean registered) {...mIIntentReceiver = new InnerReceiver(this, !registered);.... 这里也能猜到 是ActivityThread 中的那个HmActivityThread = activityThread;...}

这里就可以看 Args ,一个 Runnable, 看下 run 方法:

final class Args extends BroadcastReceiver.PendingResult implements Runnable {public void run() {final BroadcastReceiver receiver = mReceiver;final boolean ordered = mOrdered;if (ActivityThread.DEBUG_BROADCAST) {int seq = mCurIntent.getIntExtra("seq", -1);Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()+ " seq=" + seq + " to " + mReceiver);Slog.i(ActivityThread.TAG, "  mRegistered=" + mRegistered+ " mOrderedHint=" + ordered);}final IActivityManager mgr = ActivityManagerNative.getDefault();final Intent intent = mCurIntent;if (intent == null) {Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched);}mCurIntent = null;mDispatched = true;...Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");try {//获取receiver的类加载类加载ClassLoader cl =  mReceiver.getClass().getClassLoader();intent.setExtrasClassLoader(cl);intent.prepareToEnterProcess();setExtrasClassLoader(cl);receiver.setPendingResult(this);//这里回调receiver 的onReceive 方法receiver.onReceive(mContext, intent);} catch (Exception e) {...}...Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}}

这样我们就可以在 sendBroadcast 时,在 Receiver 方法中收到相应的回调了,完毕。

http://www.dinnco.com/news/10592.html

相关文章:

  • 建设一个公司网站需要什么知识人工智能培训
  • 必知的网站西安网站seo诊断
  • 如何建设一个优秀的电商网站五年级上册优化设计答案
  • 上海免费网站建设公司网页制作流程
  • 怎么做卖花的网站nba录像回放
  • 南头专业的网站建设公司域名查询ip
  • 网站流量数据分析怎么做怎么建立自己的企业网站
  • 珠海做网站方案seo关键词优化培训班
  • godady怎么做网站开封网络推广哪家好
  • 教务管理系统下载电子商务seo
  • 什么是网络营销? 你觉得网络营销的核心是什么?宁波seo外包优化公司
  • WordPress最好版本什么是优化
  • 西安公司的网站建设百度收录量查询
  • 空间网站链接怎么做网址查询
  • 网站建设seo网络推广百度普通版下载
  • 网站文章推广合肥网站seo整站优化
  • 制作网站入门厦门seo优化多少钱
  • 公需科目在哪个网站做中国万网域名注册
  • 长沙恒大最新真实消息seo快速排名软件网站
  • 北京网站外包公司合肥网络公司seo建站
  • 单网站建设夸克搜索引擎
  • 一级建造师找工作网站seo算法优化
  • 云服务器免费虚拟主机seo自动工具
  • 宜兴市建设局网站超云seo优化
  • 网站建设电销异议处理话术网站推广的主要方式
  • 平面设计速成班郴州网站seo外包
  • 高效简便的网站开发天津的网络优化公司排名
  • 凡科网是干嘛用的汕头seo优化项目
  • 网站外链分析怎么做如何优化关键词搜索
  • 做物流哪个网站推广好谷歌的推广是怎么样的推广