Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 中級開發 >> PendingIntent實現原理和代碼

PendingIntent實現原理和代碼

編輯:中級開發

對於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. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved