Android中pendingIntent的深刻理解

pendingIntent字面意义:等待的,未决定的Intent。
  pendingIntent对象,使用方法类的静态方法 :html

      getActivity(Context, int, Intent, int)------->跳转到一个activity组件、android

    getBroadcast(Context, int, Intent, int)------>打开一个广播组件网络

    getService(Context, int, Intent, int)-------->打开一个服务组件。app

  分别对应着Intent的3个行为和参数有4个,比较重要的事第三个和第一个,其次是第四个和第二个。能够看到,要获得这个对象,必须传入一个Intent做为参数,必须有context做为参数。less

  pendingIntent是一种特殊的Intent。主要的区别在于Intent的执行马上的,而pendingIntent的执行不是马上的。pendingIntent执行的操做实质上是参数传进来的Intent的操做,可是使用pendingIntent的目的在于它所包含的Intent的操做的执行是须要知足某些条件的。
主要的使用的地方和例子:通知Notificatio的发送,短消息SmsManager的发送和警报器AlarmManager的执行等等。
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一个包装。 ide

Android的状态栏通知(Notification)函数

  若是须要查看消息,能够拖动状态栏到屏幕下方便可查看消息。布局

步骤:post

  1获取通知管理器NotificationManager,它也是一个系统服务动画

  2创建通知Notification notification = new Notification(icon, null, when);

  3为新通知设置参数(好比声音,震动,灯光闪烁)

  4把新通知添加到通知管理器

发送消息的代码以下:

  //获取通知管理器

  NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)

  int icon = android.R.drawable.stat_notify_chat;

  long when = System.currentTimeMillis();//通知发生的时间为系统当前时间

  Notification notification = new Notification(icon, null, when);//新建一个通知,第一个参数为图标,第二个参数为短暂提示标题,第三个为通知时间

  notification.defaults = Notification.DEFAULT_SOUND;//发出默认声音

  notification.flags |= Notification.FLAG_AUTO_CANCEL;//点击通知后自动清除通知

  Intent openintent = new Intent(this, OtherActivity.class);

  PendingIntent contentIntent = PendingIntent.getActivity(this, 0, openintent, 0);//当点击消息时就会向系统发送openintent意图

  notification.setLatestEventInfo(this, “标题”, “我是内容", contentIntent);//setLatestEventInfo表示设置点击该通知的事件

  mNotificationManager.notify(0, notification);//第一个参数为自定义的通知惟一标识

  重点是setLatestEventInfo( )方法的最后一个参数!!!!它是一个PendingIntent!!!!!!!!!

  这里使用到了PendingIntent(pend本意是待定,不肯定的意思)

  PendingIntent能够看做是对Intent的包装。PendingIntent主要持有的信息是它所包装的Intent和当前Application的Context。正因为PendingIntent中保存有当前Application的Context,使它赋予带他程序一种执行的Intent的能力,就算在执行时当前Application已经不存在了,也能经过存在PendingIntent里的Context照样执行Intent。

 

复制代码
 1 private void showNotify(){   
 2         Notification notice=new Notification();   
 3         notice.icon=R.drawable.icon;   
 4         notice.tickerText="您有一条新的信息";   
 5         notice.defaults=Notification.DEFAULT_SOUND;   
 6         notice.when=10L;   
 7         // 100 毫秒延迟后,震动 250 毫秒,暂停 100 毫秒后,再震动 500 毫秒     
 8         //notice.vibrate = new long[] { 100, 250, 100, 500 };出错?   
 9         //notice.setLatestEventInfo(this, "通知", "开会啦", PendingIntent.getActivity(this, 0, null, 0));   
10 notice.setLatestEventInfo(this, "通知", "开会啦", PendingIntent.getActivity(this, 0, new Intent(this,Activity2.class), 0));//即将跳转页面,还没跳转   
11         NotificationManager manager=(NotificationManager)getSystemService(this.NOTIFICATION_SERVICE);   
12         manager.notify(0,notice);   
13     }  
复制代码
复制代码
 1 private void showNotify(){  
 2         Notification notice=new Notification();  
 3         notice.icon=R.drawable.icon;  
 4         notice.tickerText="您有一条新的信息";  
 5         notice.defaults=Notification.DEFAULT_SOUND;  
 6         notice.when=10L;  
 7         // 100 毫秒延迟后,震动 250 毫秒,暂停 100 毫秒后,再震动 500 毫秒    
 8         //notice.vibrate = new long[] { 100, 250, 100, 500 };出错?  
 9         //notice.setLatestEventInfo(this, "通知", "开会啦", PendingIntent.getActivity(this, 0, null, 0));  
10 notice.setLatestEventInfo(this, "通知", "开会啦", PendingIntent.getActivity(this, 0, new Intent(this,Activity2.class), 0));//即将跳转页面,还没跳转  
11         NotificationManager manager=(NotificationManager)getSystemService(this.NOTIFICATION_SERVICE);  
12         manager.notify(0,notice);  
13     }  
复制代码
复制代码
 1 1. GSM网络中Android发送短信示例
 2 
 3 Java代码 
 4 String msg ="你好,美女";   
 5 String number = "135****6784";   
 6 SmsManager sms = SmsManager.getDefault();   
 7   
 8 PendingIntent pi = PendingIntent.getBroadcast(SmsActivity.this,0,new Intent(...),0);   
 9 sms.sendTextMessage(number, null, msg, pi, null);   
10 Toast.makeText(SmsActivity.this,"发送成功",Toast.LENGHT_LONG).show();  
复制代码
复制代码
1 String msg ="你好,美女";  
2 String number = "135****6784";  
3 SmsManager sms = SmsManager.getDefault();  
4   
5 PendingIntent pi = PendingIntent.getBroadcast(SmsActivity.this,0,new Intent(...),0);  
6 sms.sendTextMessage(number, null, msg, pi, null);  
7 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的一个很好的例子:

 

短信系统举例SmsManager的用于发送短信的方法:

  sendTextMessage(destinationAddress, scAddress, text, sentIntent, deliveryIntent);

  第一个参数:destinationAddress对方手机号码

  第二个参数:scAddress短信中心号码通常设置为空

  第三个参数:text短信内容

  第四个参数:sentIntent判断短信是否发送成功,若是你没有SIM卡,或者网络中断,则能够经过这个itent来判断。注意强调的是“发送”的动做是否成功。那么至于对于对方是否收到,另当别论

  第五个参数:deliveryIntent当短信发送到收件人时,会收到这个deliveryIntent。即强调了“发送”后的结果

  就是说是在"短信发送成功"和"对方收到此短信"才会激活 sentIntent和deliveryIntent这两个Intent。这也至关因而延迟执行了Intent


  上面两个例子能够理解,PendingIntent就是一个能够在知足必定条件下执行的Intent,它相比于Intent的优点在于本身携带有Context对象,这样他就没必要依赖于某个activity才能够存在。

//////////////////////////////////////////////////////////////////////////////////////////////

PendingIntent的做用举例以及和Intent的区别

一、PendingIntent做用

  根据字面意思就知道是延迟的intent,主要用来在某个事件完成后执行特定的Action。PendingIntent包含了Intent及Context,因此就算Intent所属程序结束,PendingIntent依然有效,能够在其余程序中使用。
经常使用在通知栏及短信发送系统中。

  PendingIntent通常做为参数传给某个实例,在该实例完成某个操做后自动执行PendingIntent上的Action,也能够经过PendingIntent的send函数手动执行,并能够在send函数中设置OnFinished表示send成功后执行的动做。

二、PendingIntent举例

a. 系统通知栏

复制代码
NotificationManager nm = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
int icon = android.R.drawable.stat_notify_chat;
long when = System.currentTimeMillis() + 2000;
Notification n = new Notification(icon, "通知栏demo提醒", when);
n.defaults = Notification.DEFAULT_SOUND;
n.flags |= Notification.FLAG_AUTO_CANCEL;

Intent openintent = new Intent(this, DemoList.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, openintent, PendingIntent.FLAG_CANCEL_CURRENT);
n.setLatestEventInfo(this, "通知栏demo提醒title", "通知栏demo提醒text", pi);
nm.notify(0, n);
复制代码

  setLatestEventInfo表示设置点击该通知的事件

b. 短信系统举例

  以上的两个PendingIntent sentPI和deliveredPI将分别在短信发送成功和对方接受成功时被广播

三、Intent和PendingIntent的区别

  a. Intent是当即使用的,而PendingIntent能够等到事件发生后触发,PendingIntent能够cancel
  b. Intent在程序结束后即终止,而PendingIntent在程序结束后依然有效
  c. PendingIntent自带Context,而Intent须要在某个Context内运行
  d. Intent在原task中运行,PendingIntent在新的task中运行

PendingIntent用于描述Intent及其最终的行为. 
  你能够经过getActivity(Context context, int requestCode, Intent intent, int flags)系列方法从系统取得一个用于启动一个Activity的PendingIntent对象,

  能够经过getService(Context context, int requestCode, Intent intent, int flags)方法从系统取得一个用于启动一个Service的PendingIntent对象

  能够经过getBroadcast(Context context, int requestCode, Intent intent, int flags)方法从系统取得一个用于向BroadcastReceiver的Intent广播的PendingIntent对象

  返回的PendingIntent能够递交给别的应用程序,而后继续处理。这里的话你能够稍后才处理PendingIntent中描述的Intent及其最终行为。

  当你把PendingIntent递交给别的程序进行处理时,PendingIntent仍然拥有PendingIntent原程序所拥有的权限(with the same permissions and identity).当你从系统取得一个PendingIntent时,必定要很是当心才行。好比,一般,若是Intent目的地是你本身的component(Activity/Service/BroadcastReceiver)的话,你最好采用在Intent中显示指定目的component名字的方式,以确保Intent最终能发到目的,不然Intent最后可能不知道发到哪里了。一个PendingIntent就是Android系统中的一个token(节点,这个应该是Linux或C\C++用语)的一个对象引用,它描述了一些将用于retrieve的数据(这里,这些数据描述了Intent及其最终的行为)。

  这就意味着即便PendingIntent原进程结束了的话, PendingIntent自己仍然还存在,可在其余进程(PendingIntent被递交到的其余程序)中继续使用.若是我在从系统中提取一个PendingIntent的,而系统中有一个和你描述的PendingIntent对等的PendingInent, 那么系统会直接返回和该PendingIntent实际上是同一token的PendingIntent,而不是一个新的token和PendingIntent。然而你在从提取PendingIntent时,经过FLAG_CANCEL_CURRENT参数,让这个老PendingIntent的先cancel()掉,这样获得的pendingInten和其token的就是新的了。

  经过FLAG_UPDATE_CURRENT参数的话,可让新的Intent会更新以前PendingIntent中的Intent对象数据,例如更新Intent中的Extras。另外,咱们也能够在PendingIntent的原进程中调用PendingIntent的cancel ()把其从系统中移除掉。

 

onResume()方法

因为Bactivity的操做,影响了Aactivity的数据,因此再回到A的时候,须要A可以进行刷新操做。
可是默认跳回去的时候,A界面仍是上次那个。

解决方案:重写Aactivity的onResume()方法,在onResume()方面里进行刷新操做。由于按照activity的生命周期模型,当activity恢复的时候,onResume()方法会被调用,因此这是一个刷新的好机会。

 

 

一个Activity活动就是一个界面的布局。

程序正常启动时:onCreate()->onStart()->onResume();
onCreate()在活动第一次建立时被调用,主要用于加载布局
onStart()这个方法在活动由不可见变为可见的时候调用。
onResume这个方法在活动准备好和用户进行交互的时候调用。此时的活动必定位于返回栈的栈顶,而且处于运行状态.
三种调用的场景:
一个Activity启动另外一个Activity: onPause()->onStop(),再返回:onRestart()->onStart()->onResume()
程序按back 退出: onPause()->onStop()->onDestory(),再进入:onCreate()->onStart()->onResume();
程序按home 退出: onPause()->onStop(),再进入:onRestart()->onStart()->onResume();
生命周期的一些细节:
1     Activity 第一次建立时会调用 onCreate(Bundle)。 该方法用于建立 Activity 的用户界面,建立所需的后台线程,并执行其余的全局初始化。若是能得到Activity之前的状态,就能够将包含此状态的 android.os.Bundle 对象传给onCreate();不然就传入一个空引用。在调用 onCreate(Bundle)以后,
Android 总会调用 onStart()。
2      在用户看到 Activity 以前会调用 onStart()方法。当 Activity 进入前台时, Android在调用 onStart()以后就会调用onResume();当 Activity 变成隐藏状态时, Android就会在调用 onStart()以后调用 onStop()。
3      当 Activity 中止后,在其从新启动以前会调用 onRestart()。在调用 onRestart()以后,Android 会调用 onStart()。
4      在 Activity 开始跟用户交互以前会调用 onResume()。此时, Activity 得到了焦点,用户的输入会发送给该 Activity。当 Activity 必须暂停时,Android 就会在调用onResume()以后调用 onPause()。
5      当 Android 要恢复另外一个 Activity 时会调用 onPause()。该方法通常用于保留未保存的修改,中止可能会消耗处理器资源的动画等。它应该很快地完成工做,由于只有等该方法返回时,下一个 Activity 才能被从新激活。在调用了 onPause()以后,当 Activity 开始跟用户交互时, Android 就会使用onResume(),当 Activity 变成隐藏状态时调用 onStop()。 许多 Activity 执行 onPause()方法来提交数据的改变或者准备中止与用户的交互操做。
6      当 Activity 变为隐藏状态时会调用 onStop()。这种状况可能发生在 Activity被销毁,或者另外一个 Activity(正在运行的或新启动的)被从新激活并将覆盖前一个 Activity时。在调用 onStop()以后,若是 Activity 从新跟用户交互, Android 会调用 onRestart()方法;
7     若是 Activity 退出了,就会调用 onDestroy()方法。
8      在 Activity 被销毁以前会调用 onDestroy(),除非是内存不够, Android 强行终止了Activity 的进程。在这种状况下就不会调用 onDestroy()。若是调用了 onDestroy(),那它就是该 Activity 接收的最终调用。在 onPause()、 onStop()或 onDestroy()返回以后, Android 能够终止托管 Activity 的进程。从 onPause()返回后到调用 onResume()以前, Activity 都处于可终止状态。在 onPause()再次返回以前, Activity 都不会再处于可终止状态。

 

android onNewIntent

在Android应用程序开发的时候,从一个Activity启动另外一个Activity并传递一些数据到新的Activity上很是简单,可是当您须要让后台运行的Activity回到前台并传递一些数据可能就会存在一点点小问题。

首先,在默认状况下,当您经过Intent启到一个Activity的时候,就算已经存在一个相同的正在运行的Activity,系统都会建立一个新的Activity实例并显示出来。为了避免让Activity实例化屡次,咱们须要经过在AndroidManifest.xml配置activity的加载方式(launchMode)以实现单任务模式,以下所示:


1 <activity android:label="@string/app_name" android:launchmode="singleTask"android:name="Activity1">

2 </activity>


launchMode为singleTask的时候,经过Intent启到一个Activity,若是系统已经存在一个实例,系统就会将请求发送到这个实例上,但这个时候,系统就不会再调用一般状况下咱们处理请求数据的onCreate方法,而是调用onNewIntent方法,以下所示:


1 protected void onNewIntent(Intent intent) {

2   super.onNewIntent(intent);

3   setIntent(intent);//must store the new intent unless getIntent() will return the old one

4   processExtraData();

5 }


不要忘记,系统可能会随时杀掉后台运行的Activity,若是这一切发生,那么系统就会调用onCreate方法,而不调用onNewIntent方法,一个好的解决方法就是在onCreate和onNewIntent方法中调用同一个处理数据的方法,以下所示:


01 public void onCreate(Bundle savedInstanceState) {

02   super.onCreate(savedInstanceState);

03   setContentView(R.layout.main);

04   processExtraData();

05 }

06  

07 protected void onNewIntent(Intent intent) {

08   super.onNewIntent(intent);

09   setIntent(intent);//must store the new intent unless getIntent() will return the old one

10   processExtraData()

11 }

12  

13 private void processExtraData(){

14   Intent intent = getIntent();

15   //use the data received here

16 }

相关文章
相关标签/搜索