Android藍牙控制遙控器的源碼
http://www.eoeandroid.com/thread-195605-1-1.htmlhtml
基於Android 砸蛋的遊戲
http://www.eoeandroid.com/thread-195603-1-1.htmljava
Android下瀏覽其文件系統的工具
http://www.eoeandroid.com/thread-195591-1-1.htmlandroid
先貼上這些源碼裏面相關的文件:app
framework/base/services/java/com/android/server/NotificationManagerService.java{@hide} extends INotificationManager.Stubide
framework/base/services/java/com/android/server/StatusBarManagerService.java extends IStatusBarService.Stub函數
framework/base/core/java/com/android/internal/statusbar/StatusBarNotification implements Parcelable工具
framework/base/core/java/com/android/internal/statusbar/IStatusBar.aidlui
framework/base/core/java/com/android/internal/statusbar/IStatusBarService.aidlthis
framework/base/core/java/com/android/internal/statusbar/StatusBarNotification.aidl spa
framework/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java extends Service implements CommandQueue.Callbacks
framework/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java extends IStatusBar.Stub
1>.系統啓動的時候:framework/base/services/java/com/android/server/SystemServer.java中:
try { Slog.i(TAG, "Status Bar"); statusBar = new StatusBarManagerService(context); ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar); } catch (Throwable e) { Slog.e(TAG, "Failure starting StatusBarManagerService", e); } try { Slog.i(TAG, "Notification Manager"); notification = new NotificationManagerService(context, statusBar, lights); ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification); } catch (Throwable e) { Slog.e(TAG, "Failure starting Notification Manager", e); }
這段代碼是註冊狀態欄管理和通知管理這兩個服務。
拿addNotification方法示範:
public IBinder addNotification(StatusBarNotification notification) { synchronized (mNotifications) { IBinder key = new Binder(); mNotifications.put(key, notification); if (mBar != null) { try { mBar.addNotification(key, notification); } catch (RemoteException ex) { } } return key; } }
這裏的mBar其實就是IStatusBar的實例
volatile IStatusBar mBar;
爲了防止NPE,每次使用mBar都先判斷是否爲null,mBar是在方法registerStatusBar中傳遞進來的。
public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList, List<IBinder> notificationKeys, List<StatusBarNotification> notifications) { enforceStatusBarService(); Slog.i(TAG, "registerStatusBar bar=" + bar); mBar = bar; synchronized (mIcons) { iconList.copyFrom(mIcons); } synchronized (mNotifications) { for (Map.Entry<IBinder,StatusBarNotification> e: mNotifications.entrySet()) { notificationKeys.add(e.getKey()); notifications.add(e.getValue()); } } }
public void addNotification(IBinder key, StatusBarNotification notification) { synchronized (mList) { NotificationQueueEntry ne = new NotificationQueueEntry(); ne.key = key; ne.notification = notification; mHandler.obtainMessage(MSG_ADD_NOTIFICATION, 0, 0, ne).sendToTarget(); //這句話對應的mHandler執行語句是: // final NotificationQueueEntry ne = (NotificationQueueEntry)msg.obj; // mCallbacks.addNotification(ne.key, ne.notification); //也就是調用回調函數裏面的addNotification。 } }
在StatusBarService.java中:
mCommandQueue = new CommandQueue(this, iconList);//StatusBarService實現了CommandQueue中的CommandQueue.Callbacks接口 mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); try { //將IStatusBar實現類的對象傳遞到StatusBarManagerService.java中,這裏的mCommandQueue就是上面對應的mBar啦。 mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications); } catch (RemoteException ex) { // If the system process isn't there we're doomed anyway. }
最終執行狀態欄更新通知等事件都是在實現的CommandQueue.Callbacks裏面執行。仍是以addNotification爲例:
public void addNotification(IBinder key, StatusBarNotification notification) { boolean shouldTick = true; if (notification.notification.fullScreenIntent != null) { shouldTick = false; Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent"); try { notification.notification.fullScreenIntent.send(); } catch (PendingIntent.CanceledException e) { } } StatusBarIconView iconView = addNotificationViews(key, notification); if (iconView == null) return; //。。。如下省略N字。
大體流程就是:調用StatusBarManagerService.java中的addNotification方法->(mBar不爲空的話)執行mBar.addNotification(key, notification);->對應的是CommandQueue中的addNotification(IBinder key, StatusBarNotification notification)->CommandQueue中的mCallbacks.addNotification(ne.key, ne.notification);->StatusBarService中的addNotification。
3>.上面是提供相關功能的一些類,具體的notification的管理類是framework/base/services/java/com/android/server/NotificationManagerService.java,從該類的定義public class NotificationManagerService extends INotificationManager.Stub能夠知道
他是用來實現接口中INotificationManager中定義的相關方法並向外部提供服務的類。主要向外提供public void enqueueNotificationWithTag(String pkg, String tag, int id, Notification notification,int[] idOut)方法。該方法其實是調用public void enqueueNotificationInternal(String pkg, int callingUid, int callingPid,String tag, int id, Notification notification, int[] idOut),他裏面提供了notification的具體處理方法。
摘取部分代碼片斷看看:
if (notification.icon != 0) { StatusBarNotification n = new StatusBarNotification(pkg, id, tag, r.uid, r.initialPid, notification); if (old != null && old.statusBarKey != null) { r.statusBarKey = old.statusBarKey; long identity = Binder.clearCallingIdentity(); try { mStatusBar.updateNotification(r.statusBarKey, n); } finally { Binder.restoreCallingIdentity(identity); } } else { //省略。。。
當判斷好須要更新通知的時候調用mStatusBar.updateNotification(r.statusBarKey, n);方法,這個就是StatusBarManagerService.java中的addNotification方法,這樣就進入上面所說的處理流程了。
4>. 在3中的NotificationManagerService.java是管理notification的服務,服務嘛就是用來調用的,調用他的就是你們熟悉的NotificationManager了。
在NotificationManager.java中,有一個隱藏方法,用來獲得INotificationManager接口對應的服務提供類,也就是NotificationManagerService了。
/** @hide */ static public INotificationManager getService() { if (sService != null) { return sService; } IBinder b = ServiceManager.getService("notification"); sService = INotificationManager.Stub.asInterface(b); return sService; }
再看看更熟悉的notify方法,實際上是執行:
public void notify(String tag, int id, Notification notification) { int[] idOut = new int[1]; INotificationManager service = getService(); String pkg = mContext.getPackageName(); if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")"); try { service.enqueueNotificationWithTag(pkg, tag, id, notification, idOut); if (id != idOut[0]) { Log.w(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]); } } catch (RemoteException e) { } }
ervice.enqueueNotificationWithTag(pkg, tag, id, notification, idOut);也就是3中提到的那個對外公開的服務方法了,這樣就進入了上面提到的處理流程了。