活动重新创建意图附加内容为空
Posted
技术标签:
【中文标题】活动重新创建意图附加内容为空【英文标题】:Activity re-creation intent extras are null 【发布时间】:2014-10-20 10:25:41 【问题描述】:我的应用包含一个 MainActivity 并使用全屏片段来显示内容。 我试图在重新创建应用程序期间实现以下目标(当应用程序长时间处于后台时,被系统杀死然后被带到前台)
如果用户手动重新创建应用程序(通过从最近的应用程序列表中选择应用程序),主 Activity 应重新创建,然后应重新创建最后一个全屏片段。没问题,这是标准行为。
如果由于用户触摸推送通知而重新创建应用程序,则主 Activity 应重新创建,但不应重新创建全屏的最后一个片段。 应该创建并显示一个新的 Fragment。为什么?推送通知包含有关应显示哪种 Fragment 的信息
我的方法依赖于检查我在构建启动 Main Activity 的通知时添加的意图附加内容,为简洁起见,未显示该部分代码,但 我总是在意图中添加一些附加内容,总是
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState)
//debug
System.out.println("MainActivity.onCreate() extras:"+getIntent().getExtras());
if (savedInstanceState!=null && getIntent().getExtras()!=null)
//case 2. passing null will prevent Fragment recreation
super.onCreate(null)
else
//case 1.
super.onCreate(savedInstanceState)
...
@Override
public void onResume()
//debug
System.out.println("MainActivity.onResume() extras:"+getIntent().getExtras());
...
现在,如果应用程序根本没有运行并且通知到达,我会得到以下输出:
MainActivity.onCreate() extras: Bundle[android:viewHierarchyState=Bundle[mParcelledData....
MainActivity.onResume() extras: Bundle[android:viewHierarchyState=Bundle[mParcelledData....
当用户手动重新创建应用程序时,我得到以下输出:
MainActivity.onCreate() extras: null
MainActivity.onResume() extras: null
当应用被通知重新创建时
MainActivity.onCreate() extras: null
MainActivity.onResume() extras: Bundle[android:viewHierarchyState=Bundle[mParcelledData....
这最后一种情况不是我所期望的,不知何故,通知意图附加功能只有在调用 super.onCreate() 后才可用
关于如何实现 1. 和 2. 的任何想法?
巨型编辑: 这是通知代码,如您所见,有一个启动屏幕 Activity 将 Intent 中继到 Main Activity
GcmIntentService.java
@Override protected void onHandleIntent(Intent intent)
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty())
if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType))
sendNotification(extras.getString(KEY_CATEGORY), extras.getString(KEY_CONTENT));
GcmBroadcastReceiver.completeWakefulIntent(intent);
private void sendNotification(String category, String content)
category = evaluateCategory(category);
mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent mIntent = new Intent(this, SplashActivity.class);
mIntent.putExtra(KEY_CATEGORY, Integer.valueOf(category));
mIntent.putExtra(KEY_NEW, true);
mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(this, Integer.valueOf(category), mIntent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.logo_actionbar)
//customize notification
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(Integer.valueOf(category), mBuilder.build());
SplashActivity.java
@Override protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
Intent mIntent = getIntent();
if (mIntent.getExtras()!=null)
category = mIntent.getExtras().getInt(GcmIntentService.KEY_CATEGORY);
isNew = mIntent.getExtras().getBoolean(GcmIntentService.KEY_NEW);
final Handler handler = new Handler();
handler.postDelayed(new Runnable()
@Override
public void run()
Intent mainIntent = new Intent(SplashActivity.this, MainActivity.class);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (category!=null )
mainIntent.putExtra(GcmIntentService.KEY_CATEGORY, category);
mainIntent.putExtra(GcmIntentService.KEY_NEW, isNew);
startActivity(mainIntent);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
finish();
, SPLASH_DELAY);
【问题讨论】:
什么版本的安卓?如果您在 KitKat 通知上进行的测试与那里不同。您可以发布您的通知构建代码吗? 版本为 4.4.2。我添加了 de 通知代码,它就像这样 GcmIntentService > SplashActivity > MainActivity 你的问题解决了吗? 【参考方案1】:重写Activity提供的onNewIntent(Intent intent)方法怎么样?
Read savedInstanceState 可以为 null,getIntent() 可以在您的 GCM 中包含额外内容。
According to Android Developers:
protected void onNewIntent(意图意图)
这对于将 launchMode 设置为“singleTop”的活动调用 他们的包,或者如果客户使用了 FLAG_ACTIVITY_SINGLE_TOP 标志 调用 startActivity(Intent) 时。无论哪种情况,当活动 在活动堆栈的顶部重新启动,而不是新的 正在启动的活动实例,将调用 onNewIntent() 在具有用于重新启动的 Intent 的现有实例上 它。
Activity 在接收到新的 Intent 之前总是会暂停,所以 你可以指望 onResume() 在这个方法之后被调用。
请注意,getIntent() 仍然返回原始 Intent。您可以使用 setIntent(Intent) 将其更新为这个新的 Intent。
【讨论】:
谢谢。你拯救了我的一天。以上是关于活动重新创建意图附加内容为空的主要内容,如果未能解决你的问题,请参考以下文章