在Android应用程序开发的时候,从一个Activity启动另一个Activity并传递一些数据到新的Activity上非常简单
但是当您需要让后台运行的Activity回到前台并传递一些数据可能就会存在一点点小问题。
1.首先,在默认情况下,当您通过Intent启到一个Activity的时候,就算已经存在一个相同的正在运行的Activity,系统都会创建一个新的Activity实例并显示出来。
为了不让Activity实例化多次,我们需要通过在AndroidManifest.xml配置activity的加载方式(launchMode)以实现单任务模式
参照:Activity的四种启动模式http://blog.csdn.net/cl18652469346/article/details/53672136
注:也可以通过Intent.FLAG_ACTIVITY_SINGLE_TOP标志启动Activity,效果跟android:launchmode=”singleTask”一样
2.launchMode为singleTask的时候,通过Intent启到一个Activity,
如果系统已经存在一个实例,系统就会将请求发送到这个实例上,
但这个时候,系统就不会再调用通常情况下我们处理请求数据的onCreate方法,而是调用onNewIntent方法
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);//must store the new intent unless getIntent() will return the old one
processExtraData();
}
PS:
系统可能会随时杀掉后台运行的Activity,如果这一切发生,那么系统就会调用onCreate方法,而不调用onNewIntent方法,
一个好的解决方法就是在onCreate和onNewIntent方法中调用同一个处理数据的方法
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
processExtraData();
}
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);//must store the new intent unless getIntent() will return the old one
processExtraData()
}
private void processExtraData(){
Intent intent = getIntent();
//use the data received here
}
In a word : 当从栈中启动一个已经存在的Activity时,系统不会再执行onCreate方法,而是执行onNewIntent方法
简单的介绍两个例子:
实例1:Android 监听home键(android:launchMode=”singleTask” 与 onNewIntent(Intent intent) 的用法
它们两结合使用,可以做到监听home键(仅当发起新的Intent)。
代码如下:
AndroidManifest.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内容没有更新[延时意图]
AndroidManifest.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();
}
}