Android 通知机制原理分析概述Ø 中如何注册通知 Ø 通知机制数据结构分析 Ø 底层通知机制分析 Ø 典型流程通知机制分析中如何注册通知 Ø 在InCallScreen中注册① InScreen.java: onCreate()->registerForPhoneStates()- >mCM.registerForPreciseCallStateChanged(mHandler,PHON E_STATE_CHANGED, null);② 调用时机:设备启动后第一次拨打或者接到 时 Ø 在CallNitifier中注册① PhoneApp.java: onCreate() -> notifier = new CallNotifier(this, phone, ringer, mBtHandsfree, new CallLogAsync()); ② CallNotifier.java: 构造函数中->registerForNotifications()- >mCM.registerForNewRingingConnection(this, PHONE_NEW_RINGING_CONNECTION, null); … …③ 设备启动时自动注册中如何注册通知ØCallManager 中如何注册通知 ① PhoneApp.java, onCreate()->mCM = CallManager.getInstance();mCM.registerPhone(phone); ② CallManager.java: registerPhone()- >registerForPhoneStates(basePhone)- >phone.registerForNewRingingConnection(mHandler, EVENT_NEW_RINGING_CONNECTION, null);… … ③ CallManager 中的注册函数说明:registerForCallWaiting、 registerForInCallVoicePrivacyOff、 registerForNewRingingConnection、registerForDisconnect 等大概有10多个注册函数是用来供InCallScreen 和 CallNotifier 调用来注册相应的通知。
④ 这两套注册函数的区别:中如何注册通知Ø CallManager 中如何注册通知1和2中调用的注册函数是CallManager通过调用PhoneBase类 的注册函数来实现的他的用途是让底层上报通知到 CallManager. 3中实现的注册函数是CallManager实现了供InCallScreen 和 CallNotifier调用的也就是说,当CallManager收到底层的事 件通知后,根据上面调用的情况,决定将哪个事件通知给 InCallScreen 或者 CallNotifier.中如何注册通知Ø Phone 中如何注册通知 ① 实现了registerForCallWaiting、 registerForInCallVoicePrivacyOff、 registerForNewRingingConnection、registerForDisconnect 等大概有10多个注册函数是用来供CallManager调用实现 注册相应的通知 ② 在GsmPhone的构造函数中调用了 mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE,null);mSIMRecords.registerForRe cordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null); mCM.registerForOffOrNotAvailable(this,EVENT_RADIO_OFF _OR_NOT_AVAILABLE, null);mCM.registerForOn(this, EVENT_RADIO_ON, null); 此处的mCM正是 CommandInterface接口的实现类RIL的实例。
可以认为这 个类是java 框架中通知的发起的源头通知机制数据结构分析Ø 通知实现函数源码分析:各个类中的实现都很类似,因此只copy了CallManager中的 registerForDisconnect 作为示例进行分析 ① public void registerForDisconnect(Handler h, int what, Objectobj ) { mDisconnectRegistrants.addUnique(h, what, obj);} ② protected final RegistrantList mDisconnectRegistrants = new RegistrantList(); ③ 每一个register函数都有一个相对应的unregister函数和一 个notify函数或者在handleMessage函数中直接处理RegistrantList 源码public class RegistrantList {ArrayList registrants = new ArrayList(); // of Registrantpublic synchronized voidaddUnique(Handler h, int what, Object obj){// if the handler is already in the registrant list, remove itremove(h);add(new Registrant(h, what, obj)); }private synchronized voidinternalNotifyRegistrants (Object result, Throwable exception){for (int i = 0, s = registrants.size(); i < s ; i++) {Registrant r = (Registrant) registrants.get(i);r.internalNotifyRegistrant(result, exception);}}… …}Registrant 源码public class Registrant {public Registrant(Handler h, int what, Object obj){refH = new WeakReference(h);this.what = what;userObj = obj;}/*package*/ void internalNotifyRegistrant (Object result, Throwable exception){Handler h = getHandler();if (h == null) {clear();} else {Message msg = Message.obtain();msg.what = what;msg.obj = new AsyncResult(userObj, result, exception);h.sendMessage(msg);}}WeakReference refH;int what;Object userObj; }通知机制数据结构分析 从对前面的源码分析可知,当调用每个notify 函数或者类似下面的直接调用时,最终会调 用到register函数中指定的Message handle 的 sendMessage 函数。
mDisconnectRegistrants.notifyRegistrants((Asyn cResult) msg.obj);底层通知机制分析 根据上面的分析,我们可以得出如下的流程CallNotifilerInCallScreenCallManagerPhoneRILprocessResponse: notify to phone/callManagerhandleMessage: notify to callManagerhandleMessage: notify to CallNotifier and InCallScreenhandleMessagehandleMessage。