PendingIntent实现原理和代码
作者: Android开发网原创 时间: 2011-04-15
对于Android的Intent相关内容,可能部分初级Android开发者不知道PendingIntent是干什么的? 对于Notification和SmsManager中的sendMessage以及AlarmManager中的set这些方法中均有PendingIntent,到底PendingIntent和Intent有哪些不同呢?


一、Intent


通常Android中的Intent位于 android.content.Intent的实现比较简单,直接从Object类实现,内部主要是保存了一些String或Int、轻量级的数组,提供了一些方法主要是赋值或取值。


二、PendingIntent


这里和Intent的不同分在了android.app.PendingIntent这个包中,属于app层而不是数据存储封装的content层,从首段我们看到了PendingIntent是针对将要发生的事情,比如短信发送时,本对象用于跟踪未来短信的接收情况,主要是短信回执报告和发送成功或失败,因为GSM通讯到RIL再到移动基站的过程很漫长,通过开一个Thread等待对于我们的应用是比较麻烦和耗资源,而Android的框架层的TelephonyManager底层远程服务会跟踪,最终通过PendingIntent来跟踪,有关具体实现原理和代码如下:


public final class PendingIntent implements Parcelable { //实现了Parcelable接口,可以方便的处理二进制数据和用于远程服务的数据交换
private final IIntentSender mTarget;


public static final int FLAG_ONE_SHOT = 1<<30;
public static final int FLAG_NO_CREATE = 1<<29;
public static final int FLAG_CANCEL_CURRENT = 1<<28;
public static final int FLAG_UPDATE_CURRENT = 1<<27;


public static class CanceledException extends AndroidException {
public CanceledException() {
}


public CanceledException(String name) {
super(name);
}


public CanceledException(Exception cause) {
super(cause);
}
}


public interface OnFinished {
void onSendFinished(PendingIntent pendingIntent, Intent intent,
int resultCode, String resultData, Bundle resultExtras);
}


private static class FinishedDispatcher extends IIntentReceiver.Stub //这里Android123友情提示如果你掌握了Android的RemoteService或Java RMI这里应该好理解
implements Runnable {
private final PendingIntent mPendingIntent;
private final OnFinished mWho;
private final Handler mHandler;
private Intent mIntent;
private int mResultCode;
private String mResultData;
private Bundle mResultExtras;
FinishedDispatcher(PendingIntent pi, OnFinished who, Handler handler) {
mPendingIntent = pi;
mWho = who;
mHandler = handler;
}
public void performReceive(Intent intent, int resultCode,
String data, Bundle extras, boolean serialized, boolean sticky) {
mIntent = intent;
mResultCode = resultCode;
mResultData = data;
mResultExtras = extras;
if (mHandler == null) {
run();
} else {
mHandler.post(this);
}
}
public void run() {
mWho.onSendFinished(mPendingIntent, mIntent, mResultCode,
mResultData, mResultExtras);
}
}


public static PendingIntent getActivity(Context context, int requestCode,
Intent intent, int flags) {
String packageName = context.getPackageName();
String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
context.getContentResolver()) : null;
try {
IIntentSender target =
ActivityManagerNative.getDefault().getIntentSender(
IActivityManager.INTENT_SENDER_ACTIVITY, packageName,
null, null, requestCode, intent, resolvedType, flags);
return target != null ? new PendingIntent(target) : null;
} catch (RemoteException e) {
}
return null;
}


public static PendingIntent getBroadcast(Context context, int requestCode,
Intent intent, int flags) {
String packageName = context.getPackageName();
String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
context.getContentResolver()) : null;
try {
IIntentSender target =
ActivityManagerNative.getDefault().getIntentSender(
IActivityManager.INTENT_SENDER_BROADCAST, packageName,
null, null, requestCode, intent, resolvedType, flags);
return target != null ? new PendingIntent(target) : null;
} catch (RemoteException e) {
}
return null;
}


public static PendingIntent getService(Context context, int requestCode,
Intent intent, int flags) {
String packageName = context.getPackageName();
String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
context.getContentResolver()) : null;
try {
IIntentSender target =
ActivityManagerNative.getDefault().getIntentSender(
IActivityManager.INTENT_SENDER_SERVICE, packageName,
null, null, requestCode, intent, resolvedType, flags);
return target != null ? new PendingIntent(target) : null;
} catch (RemoteException e) {
}
return null;
}


public IntentSender getIntentSender() {
return new IntentSender(mTarget);
}


public void cancel() {
try {
ActivityManagerNative.getDefault().cancelIntentSender(mTarget);
} catch (RemoteException e) {
}
}


public void send() throws CanceledException {
send(null, 0, null, null, null);
}


public void send(int code) throws CanceledException {
send(null, code, null, null, null);
}


public void send(Context context, int code, Intent intent)
throws CanceledException {
send(context, code, intent, null, null);
}


public void send(int code, OnFinished onFinished, Handler handler)
throws CanceledException {
send(null, code, null, onFinished, handler);
}


public void send(Context context, int code, Intent intent,
OnFinished onFinished, Handler handler) throws CanceledException {
try {
String resolvedType = intent != null ?
intent.resolveTypeIfNeeded(context.getContentResolver())
: null;
int res = mTarget.send(code, intent, resolvedType,
onFinished != null
? new FinishedDispatcher(this, onFinished, handler)
: null);
if (res < 0) {
throw new CanceledException();
}
} catch (RemoteException e) {
throw new CanceledException(e);
}
}


public String getTargetPackage() {
try {
return ActivityManagerNative.getDefault()
.getPackageForIntentSender(mTarget);
} catch (RemoteException e) {
// Should never happen.
return null;
}
}


@Override
public boolean equals(Object otherObj) {
if (otherObj instanceof PendingIntent) {
return mTarget.asBinder().equals(((PendingIntent)otherObj)
.mTarget.asBinder());
}
return false;
}


@Override
public int hashCode() {
return mTarget.asBinder().hashCode();
}


@Override
public String toString() {
StringBuilder sb = new StringBuilder(128);
sb.append("PendingIntent{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
sb.append(": ");
sb.append(mTarget != null ? mTarget.asBinder() : null);
sb.append('}');
return sb.toString();
}

public int describeContents() {
return 0;
}


public void writeToParcel(Parcel out, int flags) {
out.writeStrongBinder(mTarget.asBinder());
}


public static final Parcelable.Creator<PendingIntent> CREATOR
= new Parcelable.Creator<PendingIntent>() {
public PendingIntent createFromParcel(Parcel in) {
IBinder target = in.readStrongBinder();
return target != null ? new PendingIntent(target) : null;
}


public PendingIntent[] newArray(int size) {
return new PendingIntent[size];
}
};


public static void writePendingIntentOrNullToParcel(PendingIntent sender,
Parcel out) {
out.writeStrongBinder(sender != null ? sender.mTarget.asBinder()
: null);
}


public static PendingIntent readPendingIntentOrNullFromParcel(Parcel in) {
IBinder b = in.readStrongBinder();
return b != null ? new PendingIntent(b) : null;
}


/*package*/ PendingIntent(IIntentSender target) {
mTarget = target;
}


/*package*/ PendingIntent(IBinder target) {
mTarget = IIntentSender.Stub.asInterface(target);
}


/** @hide */
public IIntentSender getTarget() {
return mTarget;
}
}


整体来说PendingIntent的实现比较简单,主要和Android特定的的远程服务打交道(短信、通知、闹铃等),通常的应用无需使用。

更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. python list.sort()根据多个关键字排序的方法实现
  3. android EditText设置不可写
  4. Android(安卓)拨号器的简单实现
  5. android实现字体闪烁动画的方法
  6. Android中不同应用间实现SharedPreferences数据共享
  7. [Android(安卓)NDK]Android(安卓)JNI开发例子 ---3 在JNI中实现o
  8. android打电话发短信
  9. android 拨打紧急号码,通话时开启免提功能实现

随机推荐

  1. Android API level与version对应关系
  2. Android AudioRecord录音实时pcm 编码为
  3. Android 8.0系统 默认赋予应用权限
  4. 多个Android device offline处理命令
  5. android之android studio的NDK环境搭建
  6. Android(安卓)客户端与服务器交互方式
  7. Android(安卓)一套完整的 Socket 解决方
  8. Android两个recyview直接的item拖动
  9. Android定义一个不消失的悬停通知栏
  10. android---菜单栏选项