[整理]Android Intent和PendingIntent的區別

        Intent是一個意圖,一個描述了想要啓動一個Activity、Broadcast或是Service的意圖。它主要持有的信息是它想要啓動的組件(Activity、Broadcast或是Service)。

        PendingIntent可以看作是對Intent的包裝。供當前App之外的其他App調用。有點“被動”或是“Callback”的意思,但不是嚴格意義上的“被動”或是“Callback”。總之,當前App不能用它馬上啓動它所包裹的Intent。而是在外部App執行這個PendingIntent時,間接地、實際地調用裏面的Intent。PendingIntent主要持有的信息是它所包裝的Intent和當前App的Context。正由於PendingIntent中保存有當前App的Context,使它賦予外部App一種能力,使得外部App可以如同當前App一樣的執行PendingIntent裏的Intent,就算在執行時當前App已經不存在了,也能通過存在PendingIntent裏的Context照樣執行Intent。

       intent英文意思是意圖,pending表示即將發生或來臨的事情。
       PendingIntent這個類用於處理即將發生的事情。比如在通知Notification中用於跳轉頁面,但不是馬上跳轉。
       Intent 是及時啓動,intent 隨所在的activity 消失而消失。
       PendingIntent 可以看作是對intent的包裝,通常通過getActivity,getBroadcast ,getService來得到pendingintent的實例,當前activity並不能馬上啓動它所包含的intent,而是在外部執行 pendingintent時,調用intent的。正由於pendingintent中 保存有當前App的Context,使它賦予外部App一種能力,使得外部App可以如同當前App一樣的執行pendingintent裏的 Intent, 就算在執行時當前App已經不存在了,也能通過存在pendingintent裏的Context照樣執行Intent。另外還可以處理intent執行 後的操作。常和alermanger 和notificationmanager一起使用。

        Intent一般是用作Activity、Sercvice、BroadcastReceiver之間傳遞數據,而Pendingintent,一般用在 Notification上,可以理解爲延遲執行的intent,PendingIntent是對Intent一個包裝。

private void showNotify(){
 
Notification notice=new Notification();
 
notice.icon=R.drawable.icon;
 
notice.tickerText=”您有一條新的信息”;
 
notice.defaults=Notification.DEFAULT_SOUND;
 
notice.when=10L;
 
// 100 毫秒延遲後,震動 250 毫秒,暫停 100 毫秒後,再震動 500 毫秒
 
//notice.vibrate = new long[] { 100, 250, 100, 500 };出錯?
 
//notice.setLatestEventInfo(this, “通知”, “開會啦”, PendingIntent.getActivity(this, 0, null, 0));
 
notice.setLatestEventInfo(this, “通知”, “開會啦”, PendingIntent.getActivity(this, 0, new Intent(this,Activity2.class), 0));//即將跳轉頁面,還沒跳轉
 
NotificationManager manager=(NotificationManager)getSystemService(this.NOTIFICATION_SERVICE);
 
manager.notify(0,notice);
 
} 

 

 1. GSM網絡中android發送短信示例

String msg =”你好,美女”;
 
String number = “135****6784″;
 
SmsManager sms = SmsManager.getDefault(); 

PendingIntent pi = PendingIntent.getBroadcast(SmsActivity.this,0,new Intent(…),0);
 
sms.sendTextMessage(number, null, msg, pi, null);
 
Toast.makeText(SmsActivity.this,”發送成功”,Toast.LENGHT_LONG).show(); 


PendingIntent就是一個Intent的描述,我們可以把這個描述交給別的程序,別的程序根據這個描述在後面的別的時間做你安排做的事情 (By giving a PendingIntent to another application, you are granting it the right to perform the operation you have specified as if the other application was yourself,就相當於PendingIntent代表了Intent)。本例中別的程序就是發送短信的程序,短信發送成功後要把intent廣播出 去 。
函數SmsManager.sendTextMessage(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)中參數解釋:

       1)PendingIntent sentIntent:當短信發出時,成功的話sendIntent會把其內部的描述的intent廣播出去,否則產生錯誤代碼並通過 android.app.PendingIntent.OnFinished進行回調,這個參數最好不爲空,否則會存在資源浪費的潛在問題;

       2)PendingIntent deliveryIntent:是當消息已經傳遞給收信人後所進行的PendingIntent廣播。
查看PendingIntent 類可以看到許多的Send函數,就是PendingIntent在進行被賦予的相關的操作。PendingIntent就是一個Intent的描述,我們可以把這個描述交給別的程序,別的程序根據這個描述在後面的別的時間做你安排做的事情 (By giving a PendingIntent to another application, you are granting it the right to perform the operation you have specified as if the other application was yourself,就相當於PendingIntent代表了Intent)。本例中別的程序就是發送短信的程序,短信發送成功後要把intent廣播出 去 。
函數SmsManager.sendTextMessage(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)中參數解釋:

       1)PendingIntent sentIntent:當短信發出時,成功的話sendIntent會把其內部的描述的intent廣播出去,否則產生錯誤代碼並通過 android.app.PendingIntent.OnFinished進行回調,這個參數最好不爲空,否則會存在資源浪費的潛在問題;

       2)PendingIntent deliveryIntent:是當消息已經傳遞給收信人後所進行的PendingIntent廣播。
查看PendingIntent 類可以看到許多的Send函數,就是PendingIntent在進行被賦予的相關的操作。

如果你的BroadcastReveiver註冊接收相應的消息,你就會收到相應的Intent,這時候就可以根據Intent的Action,執行相應的動作,這就是上面說的in the future的含義;

有三個靜態方法可以獲得PendingIntent實例:

  • public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags) 
  • public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags) 
  • public static PendingIntent getService(Context context, int requestCode, Intent intent, int flags)

flags參數有三個,我覺得英文更好理解:

FLAG_ONE_SHOT:this PendingIntent can only be used once. If set, after send() is called on it, it will be automatically canceled for you and any future attempt to send through it will fail.

FLAG_UPDATE_CURRENT: if the described PendingIntent already exists, then keep it but its replace its extra data with what is in this new Intent. This can be used if you are creating intents where only the extras change, and don't care that any entities that received your previous PendingIntent will be able to launch it with your new extras even if they are not explicitly given to it.
這個簡單解釋一下,就是當存在時,先把原來的取消,然後創建一個新的,在AlarmManager服務時,修改一個鬧鈴,用的比較笨的的方法,先取消,然後重新註冊,其實加上這個參數就行了。

要注意的是,這個只更新extra data,不會修改其他內容,不能new一個Intent,還有就是如果你的Intent中需要傳遞Id或者其他數據,一定要用這個flags或者FLAG_CANCEL_CURRENT,曾經一直接收不到Id,查了半天原來是這個原因 :-(

LAG_NO_CREATE:if the described PendingIntent does not already exist, then simply return null instead of creating it.

LAG_CANCEL_CURRENT:if the described PendingIntent already exists, the current one is canceled before generating a new one.You can use this to retrieve a new PendingIntent when you are only changing the extra data in the Intent; by canceling the previous pending intent, this ensures that only entities given the new data will be able to launch it. If this assurance is not an issue, consider FLAG_UPDATE_CURRENT.

上面4個flag中最經常使用的是FLAG_UPDATE_CURRENT,因爲描述的Intent有更新的時候需要用到這個flag去更新你的描述(確切的說是更新extra data),否則組件在下次事件發生或時間到達的時候extras永遠是第一次Intent的extras,使用FLAG_CANCEL_CURRENT也能做到更新extras,只不過是先把前面的extras清除,另外FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT的區別在於能否新new一個Intent,FLAG_CANCEL_CURRENT能夠新new一個Intent,而FLAG_UPDATE_CURRENT則不能,只能使用第一次的Intent。

還有一個問題就是怎麼區分PendingIntent,主要取消的時候要用到,requestCode可以區分,但系統還是根據Intent的Action去區分的,如果Intent設置了Class,classData,取消的時候Intent一定要設置要相同的,不然取消不掉就可能出現取消後,Alarm還會響的問題,PendingIntent用的地方蠻多的,像 Notifications, AlarmManager等都會用到。。。
      查看PendingIntent 類可以看到許多的Send函數,就是PendingIntent在進行被賦予的相關的操作。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章