一、是什麼
PendingIntent類提供了一種可以建立由其他應用程式在稍晚的時候來觸發的Intent的機制。PendingIntent通常用于包裝在響應将來的事件時要觸發的Intent。
Intent和PendingIntent的簡單區分:
a. Intent是立即使用的,而PendingIntent可以等到事件發生後觸發,PendingIntent可以cancel
b. Intent在程式結束後即終止,而PendingIntent在程式結束後依然有效
c. PendingIntent自帶Context,而Intent需要在某個Context内運作
d. Intent在原task中運作,PendingIntent在新的task中運作
你可以:
1、通過getActivity(Context context, int requestCode, Intent intent, int flags)方法從系統取得一個用于啟動一個Activity的PendingIntent對象
2、通過getService(Context context, int requestCode, Intent intent, int flags)方法從系統取得一個用于啟動一個Service的PendingIntent對象
3、通過getBroadcast(Context context, int requestCode, Intent intent, int flags)方法從系統取得一個用于向BroadcastReceiver的Intent廣播的PendingIntent對象
4、也可以通過getActivities(Context context, int requestCode,Intent[] intents, int flags)方法從系統取得一個用于啟動一系列Activity的PendingIntent對象(具體看數組Intent[]的元素數量。且此數組中的最後一個元素有特殊要求,因為沒有深入研究,這裡先不具體展開)
也就是說,使用PendingIntent,你可以将某個Intent交由另外的程式在合适的時候去執行。目前activity并不能馬上啟動它所包含的intent,而是在外部執行 pendingintent時調用intent的。正由于pendingintent中儲存有目前App的Context,使它賦予外部App一種能力,使得外部App可以如同目前App一樣的執行pendingintent裡的 Intent, 就算在執行時目前App已經不存在了,也能通過存在pendingintent裡的Context照樣執行Intent。另外還可以處理intent執行後的操作。
二、為什麼
PendingIntent的作用已經解釋了為什麼要有PendingIntent的産生。比如,建立一條通知時
notice.setLatestEventInfo(this, "通知", "開會啦", PendingIntent.getActivity(this, 0, new Intent(this,Activity2.class), 0));
使用者點選通知後執行的動作就是用一個PendingIntent來傳遞的。
作為初學者,我對PendingIntent的使用還是止步于系統提供的Api。哪些函數的參數中需要使用PendingIntent,我才會去使用它。如果有哪位大神能給講解一下自定義的函數中使用PendingIntent作為參數的,還請不吝賜教啊!!!
三、怎麼用
其實PendingIntent的使用也很簡單。既然它是對Intent的包裝,那自然少不了要先建立一個Intent執行個體,然後再根據 (一 、)中講述的方法中的一種來擷取PendingIntent的一個執行個體就可以了作為參數傳遞給其他程式使用了。下面就以我應用中的使用來舉例說明:
(看過上一篇文章的應該已經有了解了。我的這個應用是一個簡單的發短信的應用)
1、
Intent i=new Intent("com.bignerdranch.android.finishtest.SENT_SMS_ACTION");
建立Intent執行個體。這裡傳遞了一個action給這個Intent。
2、(重點部分)
PendingIntent sentIntent = PendingIntent.getBroadcast(
MainActivity.this, pendingIntentcount++, i ,PendingIntent.FLAG_UPDATE_CURRENT);
擷取PendingIntent執行個體。因為短信發送部分是使用廣播接收器來實作短信發送情況(如:是否發送成功)的擷取的,是以這裡使用了getBroadcast()來擷取執行個體。
這裡要解釋和注意兩個地方:
(1)第二個參數 簡單的解釋是:Private request code for the sender 即該Intent的發送方的私有請求碼。
首先,伺服器那邊為每一條短信都編了Id,并要求我傳回每條短信的發送狀态。但我發現如果這個參數簡單的設定為一個固定的數值的話,用于回報短信發送狀态的接收器就隻能接收到最後一個PendingIntent包含的Intent内的資訊。又通過一些上網查詢後發現,這個參數似乎能幫助我解決這個問題。其中的一篇文章給我一些啟發。既然說這是一個請求碼,那跟其它請求碼的作用應該是一樣的,就是用來做區分的。是以代碼中我把發送的PendingIntent數作為requestCode。果然實作了我想要的效果,接收器能夠接收到我發出的每一個PendingIntent并分别提取其中的Intent攜帶的資訊。
文章連結如下:http://my.oschina.net/youranhongcha/blog/196933
(2)第四個參數
可以是FLAG_NO_CREATE, FLAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT,FLAG_ONE_SHOT 或者任何 Intent.fillIn()支援的flag。
主要就是前四個啦。
對于PendingIntent.getBroadcast()函數:
FLAG_CANCEL_CURRENT(Flag indicating that if the described PendingIntent already exists, the current one should be canceled before generating a new one.)的意思是,當我們擷取PendingIntent時,如果可以從總表中查到一個相符的已存在的PendingIntentRecord節點的話,那麼需要把這個節點從總表中清理出去,也就是不會建立新的PendingIntent。
而在沒有指定FLAG_CANCEL_CURRENT的大前提下,如果使用者指定了FLAG_UPDATE_CURRENT辨別,那麼會用新的intents參數替掉剛查到的PendingIntentRecord中的舊intents。
而不管是剛清理了已存在的PendingIntentRecord,還是壓根兒就沒有找到符合的PendingIntentRecord,隻要使用者沒有明确指定FLAG_NO_CREATE(Flag indicating that if the described PendingIntent does not already exist, then simply return null instead of creating it.)辨別,系統就會盡力建立一個新的PendingIntentRecord節點,并插入總表。而指定了FLAG_NO_CREATE的話,如果所描述的PendingIntent不存在則不會建立新的PendingIntent而是直接傳回null。
FLAG_ONE_SHOT 的意思是Flag indicating that this PendingIntent can be used only once.,即該PendingIntent隻能使用一次,一旦被激發使用後機會被清理掉。
3、
smsManager.sendTextMessage(sendTo, null, MessageBody, sentIntent, null);
發送短信,并使用上面擷取的PendingIntent執行個體。