您的位置:首页 > 编程语言

PendingIntent实现原理和代码

2011-10-24 18:59 357 查看



  对于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特定的的远程服务打交道(短信、通知、闹铃等),通常的应用无需使用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息