您的位置:首页 > 其它

关于onNewIntent的使用

2016-06-15 18:00 363 查看
参考:http://blog.csdn.net/linghu_java/article/details/17266603

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

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

1

2

注:也可以通过Intent.FLAG_ACTIVITY_SINGLE_TOP标志启动Activity,效果跟android:launchmode="singleTask"一样。 

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 }

当从栈中启动一个已经存在的Activity时,系统不会再执行onCreate方法,而是执行onNewIntent方法。

总结:

(1)Activity第一启动的时候执行onCreate()---->onStart()---->onResume()等后续生命周期函数,也就时说第一次启动Activity并不会执行到onNewIntent().

(2) 而后面如果再有想启动Activity的时候,那就是执行onNewIntent()---->onResart()------>onStart()----->onResume().

(3)如果android系统由于内存不足把已存在Activity释放掉了,那么再次调用的时候会重新启动Activity即执行onCreate()---->onStart()---->onResume()等。

当调用到onNewIntent(intent)的时候,需要在onNewIntent() 中使用setIntent(intent)赋值给Activity的Intent.否则,后续的getIntent()都是得到老的Intent。

介绍两个关于onNewIntent()的使用实例

实例1:Android 监听home键(android:launchMode="singleTask" 与 onNewIntent(Intent intent) 的用法

android:launchMode="singleTask" 和 onNewIntent(Intent intent)两个特性,现总结一下经验:

android:launchMode="singleTask" 配置在 Mainifest 中,它保证了栈中此Activity总是只有一个,无论你启动它多少次;

onNewIntent(Intent intent) 是Override Activity的父类方法,只有仅在点Home键退出Activity而再次启动新的Intent进来才被调用到;

它们两结合使用,可以做到监听home键(仅当发起新的Intent)。

代码如下:

Manifest.xml

< activity android:name = ".OnNewIntentDemo"  

android:launchMode = "singleTask"

android:label = "@string/app_name" >

< intent-filter >

< action android:name = "android.intent.action.MAIN" />

< category android:name = "android.intent.category.LAUNCHER" />

</ intent-filter >

< intent-filter >

< action android:name = "android.intent.action.VIEW" />

< category android:name = "android.intent.category.DEFAULT" />

< data android:mimeType = "video/*" />

</ intent-filter >

</ activity >

Activity中代码

 @Override  

protected void onNewIntent(Intent intent) {

if (DEBUG) Log.i(TAG, "onNewIntent ~~~~~~~ intent = " +intent);

super .onNewIntent(intent);

}

实例2:发通知 PendingIntent 中Intent 内容没有更新

Xml代码

android:launchMode="singleTask" />

当我们把Activity 启动模式设置为 singleTask 之后 当我们下次 再去 用Intent 启动 这个 Activity 的时候 就不会去调用 onCreate方法 而是去调用onNewIntent()方法 然后把Intent中的数据传给它 , 前几天遇到的问题是 当我 发一个通知给状态栏 然后点击这个通知 自然会执行 PendingIntent 里边的Intent。 但是 在Activity那边的 onNewIntent()方法里边 得到的数据 不是最新的 也就是说 是 第一次的 以后 不管我怎么点通知
它都 是 第一次点击通知得到的数据,当以后再点击通知的时候其实 数据已经变了 但是 onNewIntent()方法总是得不到最新的数据, 无语了很久, 去 农民伯伯翻译组 发问得解 需要给 PendingIntent 加一个 FLAG

Java代码

PendingIntent contentIntentBegin = PendingIntent.getActivity(

notificationContext, 0, inStart, PendingIntent.FLAG_UPDATE_CURRENT);

最后一个参数就是 FLAG,这个FLAG 的 意思就是:如果系统中已存在该PendingIntent对象,那么系统将保留该PendingIntent对象,但是会使用新的Intent来更新之前PendingIntent中的Intent对象数据,例如更新Intent中的Extras。这个非常有用,例如之前提到的,我们需要在每次更新之后更新Intent中的Extras数据,达到在不同时机传递给MainActivity不同的参数,实现不同的效果。

就是 Intent里边的数据没更新而已, 很2个问题 搞了很久 才发现原来加个FLAG 就行了,有点伤不起了。!!

代码片段

Java代码

public void showNotiMessageBegin(String message, int requestCode,

String itemid) {

notification = new Notification(R.drawable.skyfile_upload_noti,

message, System.currentTimeMillis());

if (requestCode == 1 && notification.contentIntent == null) {

int index = itemid.lastIndexOf("/");

final String backPath1 = itemid

.substring(0, index == 0 ? 1 : index);

Intent inStart = new Intent(notificationContext, SkyfileActivity.class);

inStart.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

inStart.setData(Uri.parse(MetaDataView.class.getName()));

inStart.putExtra(MetaDataView.BUNDLE_PATH, backPath1);

PendingIntent contentIntentBegin = PendingIntent.getActivity(

notificationContext, 0, inStart, PendingIntent.FLAG_UPDATE_CURRENT);

notification.contentIntent = contentIntentBegin;

notification.flags |= Notification.FLAG_AUTO_CANCEL;

notification.setLatestEventInfo(notificationContext,

UPLOATTITLE, message, contentIntentBegin);

notificationMgr.notify(1, notification);

} else {

notification.contentIntent.cancel();

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: