PendingIntent
PendingIntent 将会发生的意图
主要有四种Activity、BroadcastReceiver、Service
Activity(BroadcastReceiver、Service类似只是在type不同)
/*
flags有5种
public static final int FLAG_ONE_SHOT = 1<<30; send()只会执行一次,再次send()会失败
public static final int FLAG_NO_CREATE = 1<<29; PendingIntent不存在,直接是null
public static final int FLAG_CANCEL_CURRENT = 1<<28; PendingIntent存在,生成新的会把旧的取消掉
public static final int FLAG_UPDATE_CURRENT = 1<<27; PendingIntent存在,只更新Intent
public static final int FLAG_IMMUTABLE = 1<<26; PengdingIntent存在后就不变了。
*/
public static PendingIntent getActivity(Context context, int requestCode,
@NonNull Intent intent, @Flags int flags, @Nullable Bundle options) {
String packageName = context.getPackageName();
String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
context.getContentResolver()) : null;
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(context);
IIntentSender target =
ActivityManagerNative.getDefault().getIntentSender(
ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
null, null, requestCode, new Intent[] { intent },
resolvedType != null ? new String[] { resolvedType } : null,
flags, options, UserHandle.myUserId());
//new出PendingIntent参数是target(IIntentSender客户端)
return target != null ? new PendingIntent(target) : null;
} catch (RemoteException e) {
}
return null;
}
IIntentSender target =
ActivityManagerNative.getDefault().getIntentSender(
ActivityManager.INTENT_SENDER_ACTIVITY, packageName,
null, null, requestCode, new Intent[] { intent },
resolvedType != null ? new String[] { resolvedType } : null,
flags, options, UserHandle.myUserId());
/*
type 三种
public static final int INTENT_SENDER_BROADCAST = 1;
public static final int INTENT_SENDER_ACTIVITY = 2;
public static final int INTENT_SENDER_SERVICE = 4;
*/
public IIntentSender getIntentSender(int type,
String packageName, IBinder token, String resultWho,
int requestCode, Intent[] intents, String[] resolvedTypes,
int flags, Bundle bOptions, int userId) {}
PendingIntentRecord是IIntentSender的服务端
内部类Key(重写了equals,hashCode)保存从IIntentSender客户端传来的参数数据
//ActivityManagerService.java 中保存了PendingIntent传来的参数数据在PendingIntentRecord
//使用hashmap,以PendingIntentRecord.Key做key,PendingIntentRecord弱引用做value
final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
= new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
//IIntentSender客户端传来的参数数据保存到PendingIntentRecord.Key
PendingIntentRecord.Key key = new PendingIntentRecord.Key(
type, packageName, activity, resultWho,
requestCode, intents, resolvedTypes, flags, bOptions, userId);
//生成PendingIntentRecord
rec = new PendingIntentRecord(this, key, callingUid);
//把key,value放入hashmap中
mIntentSenderRecords.put(key, rec.ref);
在PendingIntent的getActivity(或Service,BroadcastReceiver),把参数封装在AMS中的mIntentSenderRecords属性中。
PendingIntent主要结合NotificationManager进行使用的。
分析一波NotificationManager
app端主要 使用的是NotificationManager(其他的管理器获取使用类似)
NotificationManager.java
/*package*/ NotificationManager(Context context, Handler handler)
{
mContext = context;
}
/** {@hide} */
public static NotificationManager from(Context context) {
return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
主要通过ContextImpl.java
context.getSystemService(Context.NOTIFICATION_SERVICE);
ContextImpl.java
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
SystemServiceRegistry动态注册许多App端使用的各种Manager(ActivityManager,AlarmManager,NotificationManager)
//先静态注册许多服务管理器
registerService(Context.NOTIFICATION_SERVICE, NotificationManager.class,
new CachedServiceFetcher<NotificationManager>() {
@Override
public NotificationManager createService(ContextImpl ctx) {
final Context outerContext = ctx.getOuterContext();
return new NotificationManager(Context,Handler);
}});
//外部调用,获取提前静态注册的管理器
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
在获取到NotificationManager,就已经实例化了。
Notification保存要执行的参数属性(pojo)
直接实例化或通过建造者模式实例化
参数
public long when;
public int icon;
public PendingIntent contentIntent;//PendingIntent
public Uri sound;//音频
....
通过Notification封装了PendingIntent
NotificationManager通过notify把Notification发送到状态栏中
NotificationManager.java
public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
{
int[] idOut = new int[1];
INotificationManager service = getService();
。。。。。。
final Notification copy = Builder.maybeCloneStrippedForDelivery(notification);
try {
//通过aidl转到INotificationManager的服务端中在NotificationManagerService的属性
// private final IBinder mService = new INotificationManager.Stub() {}
service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
copy, idOut, user.getIdentifier());
if (localLOGV && id != idOut[0]) {
Log.v(TAG, "notify: id corrupted: sent " + id + ", got back " + idOut[0]);
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
//service的赋值
static public INotificationManager getService()
{
if (sService != null) {
return sService;
}
IBinder b = ServiceManager.getService("notification");
sService = INotificationManager.Stub.asInterface(b);
return sService;
}
在NotificationManagerService的类中
联系点1
关注
//INotificationManager的服务端的实现
private final IBinder mService = new INotificationManager.Stub() {
@Override
//INotificationManager的实现的接口方法
//作用是把跨进程的INotificationListener接口实现对象 注册进来
public void registerListener(final INotificationListener listener,
final ComponentName component, final int userid) {
enforceSystemOrSystemUI("INotificationManager.registerListener");
//进一步调用ManagedServices,registerService 封装起来
mListeners.registerService(listener, component, userid);
}
}
//是ManagedServices的子类的实现
private NotificationListeners mListeners;
NotificationListeners类是ManagedServices的子类
关注
ManagedServices.java
protected final ArrayList<ManagedServiceInfo> mServices = new ArrayList<ManagedServiceInfo>();
//抽象方法子类NotificationListeners实现
abstract protected void onServiceAdded(ManagedServiceInfo info);
public void registerService(IInterface service, ComponentName component, int userid) {
checkNotNull(service);
//把INotificationListener接口实现对象
//封装到ManagedServiceInfo
ManagedServiceInfo info = registerServiceImpl(service, component, userid);
if (info != null) {
//抽象类子类实现
onServiceAdded(info);
}
}
NotificationListeners子类实现ManagedServices
public void onServiceAdded(ManagedServiceInfo info) {
//ManagedServiceInfo 获取service
final INotificationListener listener = (INotificationListener) info.service;
final NotificationRankingUpdate update;
synchronized (mNotificationList) {
updateNotificationGroupsDesiredLocked();
update = makeRankingUpdateLocked(info);
}
try {
//进行跨进程回调
//跨进程INotificationListener回调
listener.onListenerConnected(update);
} catch (RemoteException e) {
// we tried
}
}
ManagedServiceInfo类(pojo)存储信息,并使用service(IInterface )进行回调
关注属性
public IInterface service;
public ServiceConnection connection;
介绍完上面,接下来介绍如何启动状态栏PhoneStatusBar,BaeStatusBar,会操作Nitiofication
首先从SystemServer#startOtherServices
然后通过AMS的
mActivityManagerService.systemReady(new Runnable() {
@Override
public void run() {
。。。。。。
try {
startSystemUi(context);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
。。。。。。
}
}
//拉起一个服务开启系统UI的服务
static final void startSystemUi(Context context) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
//Slog.d(TAG, "Starting service: " + intent);
//把SystemUIApplication进程启动起来
//进程名字android:process="com.android.systemui"
context.startServiceAsUser(intent, UserHandle.OWNER);
}
拉起SystemUIService把SytemUI的app启动
SystemUIService.java
@Override
public void onCreate() {
super.onCreate();
//调用SystemUIApplication#startServicesIfNeeded
((SystemUIApplication) getApplication()).startServicesIfNeeded();
}
SystemUIApplication.java
//要启动的SystemUI
private final Class<?>[] SERVICES = new Class[] {
com.android.systemui.tuner.TunerService.class,
com.android.systemui.keyguard.KeyguardViewMediator.class,
com.android.systemui.recents.Recents.class,
com.android.systemui.volume.VolumeUI.class,
com.android.systemui.statusbar.SystemBars.class,
com.android.systemui.usb.StorageNotification.class,
com.android.systemui.power.PowerUI.class,
com.android.systemui.media.RingtonePlayer.class,
com.android.systemui.keyboard.KeyboardUI.class,
};
//这个通过主线程才能调用
public void startServicesIfNeeded() {
if (mServicesStarted) {
return;
}
。。。。。。。
final int N = SERVICES.length;
//一个一个把SysytemUI的子类进行实现
//并执行对应的方法
for (int i=0; i<N; i++) {
Class<?> cl = SERVICES[i];
if (DEBUG) Log.d(TAG, "loading: " + cl);
try {
mServices[i] = (SystemUI)cl.newInstance();
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InstantiationException ex) {
throw new RuntimeException(ex);
}
mServices[i].mContext = this;
//hashmap的<Class,Object>
mServices[i].mComponents = mComponents;
mServices[i].start();
if (mBootCompleted) {
mServices[i].onBootCompleted();
}
}
mServicesStarted = true;
}
通过各个子类实现start()方法,执行各个子类定制的属性和逻辑关系
关注子类SystemBars类
SystemBars.java且实现了ServiceMonitor.Callbacks
@Override
public void start() {
if (DEBUG) Log.d(TAG, "start");
//实例化ServiceMonitor
mServiceMonitor = new ServiceMonitor(TAG, DEBUG,
mContext, Settings.Secure.BAR_SERVICE_COMPONENT, this);
// will call onNoService if no remote service is found
mServiceMonitor.start();
}
/*
ServiceMonitor#start()
主要作用,设置了动态广播,绑定服务,以及正常的逻辑
使用handler进行线程调度,确保线程是在主线程上
通过handler来完成ServiceMonitor.Callbacks的实例的回调
主要回调onNoService(),子类实现
*/
//子类实现ServiceMonitor.Callbacks#onNoService()
@Override
public void onNoService() {
if (DEBUG) Log.d(TAG, "onNoService");
createStatusBarFromConfig(); // fallback to using an in-process implementation
}
private void createStatusBarFromConfig() {
........
//config_statusBarComponent保存的字符串是
//com.android.systemui.statusbar.phone.PhoneStatusBar
//父类是com.android.systemui.statusbar.BaseStatusBar
final String clsName = mContext.getString(R.string.config_statusBarComponent);
......
Class<?> cls = null;
try {
//反射
cls = mContext.getClassLoader().loadClass(clsName);
} catch (Throwable t) {
throw andLog("Error loading status bar component: " + clsName, t);
}
try {
//实例化
mStatusBar = (BaseStatusBar) cls.newInstance();
} catch (Throwable t) {
throw andLog("Error creating status bar component: " + clsName, t);
}
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mComponents;
//启动start()
//最终把PhoneStatusBar以及父类BaseStatusBar实例化并启动
mStatusBar.start();
if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
}
在BaseStatusBar#start()
关注
BaseStatusBar.java
public void start() {
.....
//状态栏服务IStatusBarService客户端mBarService
//由于是单例与StatusBarManager获得 IStatusBarService客户端同一个
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
//为已经启动的SystemUI的子类Recent设置回调函数
//Recent触发RecentsActivity
mRecents = getComponent(Recents.class);
mRecents.setCallback(this);
....
// Connect in to the status bar manager service
StatusBarIconList iconList = new StatusBarIconList();
//CommandQueue是IStatusBar接口跨进程,目的是回调
//CommandQueue.CallBack内部接口,在PhoneStatusBar进行实现
mCommandQueue = new CommandQueue(this, iconList);
int[] switches = new int[8];
ArrayList<IBinder> binders = new ArrayList<IBinder>();
try {
//把IStatusBar接口实例注册到IStatusBarService接口中
//便于回调IStatusBarService方法,间接回调IStatusBar方法
//再次回调CommandQueue.CallBack内部接口方法
mBarService.registerStatusBar(mCommandQueue, iconList, switches, binders);
} catch (RemoteException ex) {
// If the system process isn't there we're doomed anyway.
}
//添加状态栏
createAndAddWindows();
.......
// Set up the initial notification state.
try {
//调用NotificationListenerService 的registerAsSystemService
mNotificationListener.registerAsSystemService(mContext,
new ComponentName(mContext.getPackageName(), getClass().getCanonicalName()),
UserHandle.USER_ALL);
} catch (RemoteException e) {
Log.e(TAG, "Unable to register notification listener", e);
}
。。。。。
}
//子类实现
protected abstract void createAndAddWindows();
private NotificationClicker mNotificationClicker = new NotificationClicker();
//在BaseStatusBar很多内部类
private final class NotificationClicker implements View.OnClickListener {
public void onClick(final View v) {
......
//获取状态栏下滑的点击的区域view
final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
//得到对应的StatusBarNotification 封装这Notification
//Notification又封装PendingIntent
final StatusBarNotification sbn = row.getStatusBarNotification();
.....
final PendingIntent intent = sbn.getNotification().contentIntent;
。。。。。
if (intent != null) {
//最终执行PendingIntent,响应activity,receiver service
try {
intent.send();
} catch (PendingIntent.CanceledException e) {
。。。。。
}
。。。。。。
}
}
}
//和Notification相关的内部类
//这是一个服务,
private final NotificationListenerService mNotificationListener =
new NotificationListenerService() {
@Override
public void onListenerConnected() {
。。。。。
//父类空方法,子类重写
addNotification(sbn, currentRanking, null /* oldEntry */);
。。。。。。。
}
@Override
public void onNotificationPosted(final StatusBarNotification sbn,
final RankingMap rankingMap) {
......
if (isUpdate) {
updateNotification(sbn, rankingMap);
} else {
addNotification(sbn, rankingMap, null /* oldEntry */);
}
.......
}
@Override
public void onNotificationRemoved(StatusBarNotification sbn,
final RankingMap rankingMap) {
if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn);
if (sbn != null) {
final String key = sbn.getKey();
mHandler.post(new Runnable() {
@Override
public void run() {
removeNotification(key, rankingMap);
}
});
}
}
@Override
public void onNotificationRankingUpdate(final RankingMap rankingMap) {
if (DEBUG) Log.d(TAG, "onRankingUpdate");
if (rankingMap != null) {
mHandler.post(new Runnable() {
@Override
public void run() {
updateNotificationRanking(rankingMap);
}
});
} }
};
//与上面分析的 联系点1 进行关联
// 当回调INotificationListener的方法,就会在这里具体执行
//间接调用NotificationListenerService的方法,子类在BaseStatusBar的内部NotificationListenerService重写
//又间接调用BaseStatusBar自己的方法,由子类再次PhoneStatusBar重写实现
关于Click事件监听
主要通过上面流程,把Notification拿出来,封装在View中,设置点击相应PendingIntent
大功告成
NotificationListenerService.java
//这个服务通过xml静态注册,
@SystemApi
public void registerAsSystemService(Context context, ComponentName componentName,
int currentUser) throws RemoteException {
mSystemContext = context;
if (mWrapper == null) {
//实例化内部类
mWrapper = new INotificationListenerWrapper();
}
//获得客户端INotificationManager
INotificationManager noMan = getNotificationInterface();
//把INotificationListener接口实例注册到INotificationManager 接口中
//与上面分析的联系点1进行关联
noMan.registerListener(mWrapper, componentName, currentUser);
mCurrentUser = currentUser;
}
//内部类INotificationListener服务端
private class INotificationListenerWrapper extends INotificationListener.Stub {
@Override
public void onNotificationPosted(IStatusBarNotificationHolder sbnHolder,
NotificationRankingUpdate update) {
StatusBarNotification sbn;
try {
sbn = sbnHolder.get();
} catch (RemoteException e) {
Log.w(TAG, "onNotificationPosted: Error receiving StatusBarNotification", e);
return;
}
.......
// protect subclass from concurrent modifications of (@link mNotificationKeys}.
synchronized (mWrapper) {
applyUpdate(update);
try {
if (sbn != null) {
NotificationListenerService.this.onNotificationPosted(sbn, mRankingMap);
} else {
// still pass along the ranking map, it may contain other information
NotificationListenerService.this.onNotificationRankingUpdate(mRankingMap);
}
} catch (Throwable t) {
Log.w(TAG, "Error running onNotificationPosted", t);
}
}
}
@Override
public void onNotificationRemoved(IStatusBarNotificationHolder sbnHolder,
NotificationRankingUpdate update) {
StatusBarNotification sbn;
try {
sbn = sbnHolder.get();
} catch (RemoteException e) {
Log.w(TAG, "onNotificationRemoved: Error receiving StatusBarNotification", e);
return;
}
// protect subclass from concurrent modifications of (@link mNotificationKeys}.
synchronized (mWrapper) {
applyUpdate(update);
try {
NotificationListenerService.this.onNotificationRemoved(sbn, mRankingMap);
} catch (Throwable t) {
Log.w(TAG, "Error running onNotificationRemoved", t);
}
}
}
@Override
public void onListenerConnected(NotificationRankingUpdate update) {
// protect subclass from concurrent modifications of (@link mNotificationKeys}.
synchronized (mWrapper) {
applyUpdate(update);
try {
NotificationListenerService.this.onListenerConnected();
} catch (Throwable t) {
Log.w(TAG, "Error running onListenerConnected", t);
}
}
}
@Override
public void onNotificationRankingUpdate(NotificationRankingUpdate update)
throws RemoteException {
// protect subclass from concurrent modifications of (@link mNotificationKeys}.
synchronized (mWrapper) {
applyUpdate(update);
try {
NotificationListenerService.this.onNotificationRankingUpdate(mRankingMap);
} catch (Throwable t) {
Log.w(TAG, "Error running onNotificationRankingUpdate", t);
}
}
}
@Override
public void onListenerHintsChanged(int hints) throws RemoteException {
try {
NotificationListenerService.this.onListenerHintsChanged(hints);
} catch (Throwable t) {
Log.w(TAG, "Error running onListenerHintsChanged", t);
}
}
@Override
public void onInterruptionFilterChanged(int interruptionFilter) throws RemoteException {
try {
NotificationListenerService.this.onInterruptionFilterChanged(interruptionFilter);
} catch (Throwable t) {
Log.w(TAG, "Error running onInterruptionFilterChanged", t);
}
}
}
PhoneStatusBar.java
@Override
public void createAndAddWindows() {
addStatusBarWindow();
}
private void addStatusBarWindow() {
//创建状态栏view
makeStatusBarView();
//创建状态栏管理器,持有WindowManager
mStatusBarWindowManager = new StatusBarWindowManager(mContext);
//把状态栏的mStatusBarWindow view,addview到WindowManager
//进行显示
mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
}
@Override
public void start() {
mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
updateDisplaySize();
mScrimSrcModeEnabled = mContext.getResources().getBoolean(
R.bool.config_status_bar_scrim_behind_use_src);
super.start(); // calls createAndAddWindows()
。。。。
//添加导航栏
addNavigationBar();
。。。。。。
}
//添加在WindowManager并显示
private void addNavigationBar() {
if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
if (mNavigationBarView == null) return;
prepareNavigationBarView();
mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
}