创建
调用封装好的接口创建PI
PendingIntent pi = PendingIntent.getActivity(mContext, 0, new Intent("com.a.b"), 0);
Notification n = new Notification.Builder()
.setContentIntent(pi)
..
.build();
原理
总结
- app 端会调用AMS 获取 PIRecord
- AMS 创建PIRecord 后,会自己保存一份,再返回给app
app中调用AMS获取PendingIntentRecord,封装成PendingIntent
class PendingIntent {
static PendingIntent getActivity(.., Intent intent, .) {
...
try {
..
// 调用AMS,获取PIRecord
IIntentSender target =
ActivityManger.getService().getIntentSender(
ActivityManager.INTENT_SENDER_ACTIVITY,
...,
new Intent[] {intent},
...
);
// 封装 PIRecord。
return target != null ? new PendingIntent(target) : null;
}
}
}
AMS 创建PendingIntentRecord并返回
描述
- AMS 创建PIRecord,intent的数据保存在 PIRecord.key里
- AMS还会保存这个Record 在 AMS.mPendingIntentController.mIntentSenderRecords 里
- 把Record返回给app
代码
class AMS {
IIntentSender getIntentSender(..., Intent[] intents, ...) {
...
// 创建 PendingIntentRecord并返回。并保存到 PendingIntentController.mIntentSenderRecords 里。
// intents会保存到 PIRecord.key 里
return mPendingIntentController.getIntentSender(..., intents, ...);
}
}
发送PendingIntent
封装接口的使用
pendingIntent.send();
原理
app端
描述
把PendingIntentRecord 传给AMS,去发送这个Intent
代码
class PendingIntent {
void send() {
send(...);
}
void send(...) {
if (sendAndReturnResult(...) < 0) { // 在if里执行的
}
}
int sendAndReturnResult(...) {
try {
.
return ActivityManager.getService().sendIntentSender(
mTarget, // mTarget 这个是AMS返回来的Binder:PendingIntentRecord
...
);
}
}
}
AMS端
描述
把创建PI时的Intent,传给ATMS继续处理
代码
class AMS {
int sendIntentSender(IIntentSender target, ...) {
...
if (target instanceof PendingIntentRecord) {
return target.sendWithResult(...);
}
}
}
我们创建PendingIntent时,就传了 intent,这个intent被保存在 PIRecord.key.allIntents 和 PIRecord.key.requestIntent 里
class PIRecord {
int sendWithResult(...) {
return sendInner(...);
}
int sendInner(...) {
...
// 这个就是创建 PendingIntent 时的 Intent
finalIntent = key.requestIntent != null ? new Intent(key.requestIntent) : new Intent();
...
try {
...
switch (key.type) {
case ActivityManager.intent_sender_activity:
try {
if (key.allIntents.length > 1) {
} else {
res = controller.mAtmInternal.startActivityInPackage(
...,
finalIntent,
...
)
}
}
break;
}
}
}
}
ATMS端
描述
用ActivityStart 来发送Intent,就像Context.startActivity() 了
代码
class ATMS {
class LocalService {
int startActivityInPackage(..., Intent intent, ...) {
..
return getActivityStartController().startActivityInPackge(..., intent, ...);
}
}
}