publicclassSubscriberMethod{ final Method method; final ThreadMode threadMode; final Class<?> eventType; finalint priority; finalboolean sticky; /** Used for efficient comparison */ String methodString;
// ... }
// 订阅方法描述,实体类(当前类中的订阅方法) finalclassSubscription{ final Object subscriber; // 订阅者(MainActivity.this) final SubscriberMethod subscriberMethod; // 订阅方法 /** * Becomes false as soon as {@link EventBus#unregister(Object)} is called, which is checked by queued event delivery * {@link EventBus#invokeSubscriber(PendingPost)} to prevent race conditions. */ volatileboolean active; }
/** This class is generated by EventBus, do not edit. */ publicclassMyEventBusIndeximplementsSubscriberInfoIndex{ privatestaticfinal Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX;
static { SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>();
putIndex(new SimpleSubscriberInfo(com.hearing.eventbusdemo.MainActivity.class, true, new SubscriberMethodInfo[] { new SubscriberMethodInfo("onEvent1", com.hearing.eventbusdemo.MessageEvent.class, ThreadMode.MAIN), new SubscriberMethodInfo("onEvent2", com.hearing.eventbusdemo.MessageEvent.class, ThreadMode.MAIN), }));
staticclassFindState{ final List<SubscriberMethod> subscriberMethods = new ArrayList<>(); final Map<Class, Object> anyMethodByEventType = new HashMap<>(); final Map<String, Class> subscriberClassByMethodKey = new HashMap<>(); final StringBuilder methodKeyBuilder = new StringBuilder(128);
privatevoidcheckPostStickyEventToSubscription(Subscription newSubscription, Object stickyEvent){ if (stickyEvent != null) { // If the subscriber is trying to abort the event, it will fail (event is not tracked in posting state) // --> Strange corner case, which we don't take care of here. postToSubscription(newSubscription, stickyEvent, isMainThread()); } }
publicvoidpostSticky(Object event){ synchronized (stickyEvents) { stickyEvents.put(event.getClass(), event); } // Should be posted after it is putted, in case the subscriber wants to remove immediately // 将粘性事件发送给已有的事件订阅者 post(event); }
@Override publicvoidonCreate(){ super.onCreate(); MyEventBus.getInstance().register(this); new Thread(new Runnable() { @Override publicvoidrun(){ Utils.sleep(1000); // 主进程发送事件 MyEventBus.getInstance().post("A message from main process at " + System.currentTimeMillis()); } }).start(); }
/** * Create a new Messenger pointing to the given Handler. Any Message * objects sent through this Messenger will appear in the Handler as if * {@link Handler#sendMessage(Message) Handler.sendMessage(Message)} had * been called directly. * * @param target The Handler that will receive sent messages. */ publicMessenger(Handler target){ mTarget = target.getIMessenger(); } /** * Send a Message to this Messenger's Handler. * * @param message The Message to send. Usually retrieved through * {@link Message#obtain() Message.obtain()}. * * @throws RemoteException Throws DeadObjectException if the target * Handler no longer exists. */ publicvoidsend(Message message)throws RemoteException { mTarget.send(message); } /** * Retrieve the IBinder that this Messenger is using to communicate with * its associated Handler. * * @return Returns the IBinder backing this Messenger. */ public IBinder getBinder(){ return mTarget.asBinder(); } /** * Comparison operator on two Messenger objects, such that true * is returned then they both point to the same Handler. */ publicbooleanequals(Object otherObj){ if (otherObj == null) { returnfalse; } try { return mTarget.asBinder().equals(((Messenger)otherObj) .mTarget.asBinder()); } catch (ClassCastException e) { } returnfalse; }
publicvoidwriteToParcel(Parcel out, int flags){ out.writeStrongBinder(mTarget.asBinder()); }
publicstaticfinal Parcelable.Creator<Messenger> CREATOR = new Parcelable.Creator<Messenger>() { public Messenger createFromParcel(Parcel in){ IBinder target = in.readStrongBinder(); return target != null ? new Messenger(target) : null; }
public Messenger[] newArray(int size) { returnnew Messenger[size]; } };
/** * Convenience function for writing either a Messenger or null pointer to * a Parcel. You must use this with {@link #readMessengerOrNullFromParcel} * for later reading it. * * @param messenger The Messenger to write, or null. * @param out Where to write the Messenger. */ publicstaticvoidwriteMessengerOrNullToParcel(Messenger messenger, Parcel out){ out.writeStrongBinder(messenger != null ? messenger.mTarget.asBinder() : null); } /** * Convenience function for reading either a Messenger or null pointer from * a Parcel. You must have previously written the Messenger with * {@link #writeMessengerOrNullToParcel}. * * @param in The Parcel containing the written Messenger. * * @return Returns the Messenger read from the Parcel, or null if null had * been written. */ publicstatic Messenger readMessengerOrNullFromParcel(Parcel in){ IBinder b = in.readStrongBinder(); return b != null ? new Messenger(b) : null; } /** * Create a Messenger from a raw IBinder, which had previously been * retrieved with {@link #getBinder}. * * @param target The IBinder this Messenger should communicate with. */ publicMessenger(IBinder target){ mTarget = IMessenger.Stub.asInterface(target); } }
// ThreadLocal.java public T get(){ Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { T result = (T)e.value; return result; } } return setInitialValue(); }
Message prev = null; Message p = mMessages; if (when != 0) { while (p != null && p.when <= when) { prev = p; p = p.next; } } if (prev != null) { // invariant: p == prev.next msg.next = p; prev.next = msg; } else { msg.next = p; mMessages = msg; } return token; } }
publicvoidremoveSyncBarrier(int token){ synchronized (this) { Message prev = null; Message p = mMessages; while (p != null && (p.target != null || p.arg1 != token)) { prev = p; p = p.next; } if (p == null) { thrownew IllegalStateException("The specified message queue synchronization " + " barrier token has not been posted or has already been removed."); } finalboolean needWake; if (prev != null) { prev.next = p.next; needWake = false; } else { mMessages = p.next; needWake = mMessages == null || mMessages.target != null; } p.recycleUnchecked();
// If the loop is quitting then it is already awake. // We can assume mPtr != 0 when mQuitting is false. if (needWake && !mQuitting) { nativeWake(mPtr); } } }
booleanenqueueMessage(Message msg, long when){ if (msg.target == null) { thrownew IllegalArgumentException("Message must have a target."); } if (msg.isInUse()) { thrownew IllegalStateException(msg + " This message is already in use."); }
synchronized (this) { if (mQuitting) { msg.recycle(); returnfalse; }
msg.markInUse(); // 标记为in use msg.when = when; Message p = mMessages; boolean needWake; if (p == null || when == 0 || when < p.when) { // New head, wake up the event queue if blocked. msg.next = p; mMessages = msg; needWake = mBlocked; } else { // Inserted within the middle of the queue. Usually we don't have to wake // up the event queue unless there is a barrier at the head of the queue // and the message is the earliest asynchronous message in the queue. needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; // 将队列中的Message按照处理时间先后插入 for (;;) { prev = p; p = p.next; if (p == null || when < p.when) { break; } if (needWake && p.isAsynchronous()) { needWake = false; } } msg.next = p; // invariant: p == prev.next prev.next = msg; }
// We can assume mPtr != 0 because mQuitting is false. if (needWake) { nativeWake(mPtr); } } returntrue; }
int pendingIdleHandlerCount = -1; // -1 only during first iteration int nextPollTimeoutMillis = 0; for (;;) { // 本地方法, 释放CPU资源,-1表示一直等待 nativePollOnce(ptr, nextPollTimeoutMillis);
// Process the quit message now that all pending messages have been handled. if (mQuitting) { dispose(); returnnull; }
// 处理IdleHandler的逻辑 if (pendingIdleHandlerCount < 0 && (mMessages == null || now < mMessages.when)) { pendingIdleHandlerCount = mIdleHandlers.size(); } if (pendingIdleHandlerCount <= 0) { // No idle handlers to run. Loop and wait some more. mBlocked = true; continue; }
if (mPendingIdleHandlers == null) { mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)]; } mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers); }
// 循环遍历所有IdleHandler for (int i = 0; i < pendingIdleHandlerCount; i++) { final IdleHandler idler = mPendingIdleHandlers[i]; mPendingIdleHandlers[i] = null; // release the reference to the handler
// Reset the idle handler count to 0 so we do not run them again. pendingIdleHandlerCount = 0; // 在处理IdleHandler的时候,一个新的Message可能已经下发了,因此不等待直接循环查找 nextPollTimeoutMillis = 0; } }
privatestaticvoidprepare(boolean quitAllowed){ if (sThreadLocal.get() != null) { thrownew RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); }
privateLooper(boolean quitAllowed){ mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); }
publicstaticvoidloop(){ final Looper me = myLooper(); // 要先调用Looper.prepare()方法 if (me == null) { thrownew RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; // ...
for (;;) { Message msg = queue.next(); // 可能阻塞 if (msg == null) { // No message indicates that the message queue is quitting. return; }
public Looper getLooper(){ if (!isAlive()) { returnnull; } // If the thread has been started, wait until the looper has been created. synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; }
@NonNull public Handler getThreadHandler(){ if (mHandler == null) { mHandler = new Handler(getLooper()); } return mHandler; }
// 同步阻塞运行 publicfinalbooleanrunWithScissors(final Runnable r, long timeout){ if (r == null) { thrownew IllegalArgumentException("runnable must not be null"); } if (timeout < 0) { thrownew IllegalArgumentException("timeout must be non-negative"); } // 当前线程跟当前Handler都指向同一个Looper则直接运行 if (Looper.myLooper() == mLooper) { r.run(); returntrue; }
BlockingRunnable br = new BlockingRunnable(r); return br.postAndWait(this, timeout); }
for (MediaController m : controllers) { if ("com.android.server.telecom".equals(m.getPackageName())) {
if (isAnswer) { m.dispatchMediaButtonEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK)); } else { long now = SystemClock.uptimeMillis(); m.dispatchMediaButtonEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK, 1, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_LONG_PRESS, InputDevice.SOURCE_KEYBOARD)); }
m.dispatchMediaButtonEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK)); Log.d(TAG, "headset sent to tel"); break; } } } catch (SecurityException e) { Log.d(TAG, "Permission error, Access to notification not granted to the app."); } }
publicvoidregisterListener(IStatusChgListener listener){ for (WeakReference w : mWRListener) { IStatusChgListener l = (IStatusChgListener) w.get(); if (l == listener) { return; } } WeakReference<IStatusChgListener> w = new WeakReference<>(listener); mWRListener.add(w); }
publicvoidunregisterListener(IStatusChgListener listener){ for (WeakReference w : mWRListener) { IStatusChgListener l = (IStatusChgListener) w.get(); if (l == listener) { w.clear(); break; } } }
publicfinalclassActivityThreadextendsClientTransactionHandler{ // 创建ApplicationThread对象 final ApplicationThread mAppThread = new ApplicationThread(); final Looper mLooper = Looper.myLooper(); // class H extends Handler final H mH = new H(); // 当前进程中首次初始化的app对象 Application mInitialApplication; final ArrayList<Application> mAllApplications = new ArrayList<Application>(); // 标记当前进程是否为system进程 boolean mSystemThread = false; // 记录system进程的ContextImpl对象 private ContextImpl mSystemContext; private ContextImpl mSystemUiContext;
final ArrayMap<String, WeakReference<LoadedApk>> mPackages = new ArrayMap<>(); final ArrayMap<String, WeakReference<LoadedApk>> mResourcePackages = new ArrayMap<>(); final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>(); final ArrayMap<IBinder, Service> mServices = new ArrayMap<>(); staticvolatile Handler sMainThreadHandler; // set once in main() privatestaticvolatile ActivityThread sCurrentActivityThread;
publicstatic ActivityThread systemMain(){ // The system process on low-memory devices do not get to use hardware // accelerated drawing, since this can add too much overhead to the // process. if (!ActivityManager.isHighEndGfx()) { ThreadedRenderer.disable(true); } else { ThreadedRenderer.enableForegroundTrimming(); } ActivityThread thread = new ActivityThread(); thread.attach(true, 0); return thread; }
public ClassLoader getClassLoader(){ synchronized (this) { if (mClassLoader == null) { createOrUpdateClassLoaderLocked(null/*addedPaths*/); } return mClassLoader; } }
privatevoidcreateOrUpdateClassLoaderLocked(List<String> addedPaths){ if (mPackageName.equals("android")) { // Note: This branch is taken for system server and we don't need to setup // jit profiling support. if (mClassLoader != null) { // nothing to update return; }
// Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line. // It will be in the format "seq=114" // ... ActivityThread thread = new ActivityThread(); thread.attach(false, startSeq);