活动重新创建意图附加项为空

use*_*003 5 notifications android android-intent activity-lifecycle android-fragments

我的应用程序包含MainActivity并使用全屏片段来显示内容.我正在尝试在应用程序重新创建期间实现以下功能(当应用程序已经在后台运行了很长时间,被系统杀死然后它被带到了前台)

  1. 如果用户手动重新创建应用程序(通过从最近的应用程序列表中选择应用程序),则应重新创建主活动,然后重新创建全屏的最后一个片段.没问题,这是标准行为.

  2. 如果由于用户触摸推送通知而重新创建应用程序,则应重新创建主活动,但不应重新创建全屏中的最后一个片段.而是应该创建和显示新的片段.为什么?推送通知包含有关应显示哪种片段的信息

我的方法依赖于检查我在构建启动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());
    ...
}
Run Code Online (Sandbox Code Playgroud)

现在,如果应用程序根本没有运行并且通知到达,我会得到以下输出:

MainActivity.onCreate() extras: Bundle[{android:viewHierarchyState=Bundle[mParcelledData....
MainActivity.onResume() extras: Bundle[{android:viewHierarchyState=Bundle[mParcelledData....
Run Code Online (Sandbox Code Playgroud)

当用户手动重新创建应用程序时,我得到以下输出:

MainActivity.onCreate() extras: null
MainActivity.onResume() extras: null
Run Code Online (Sandbox Code Playgroud)

通过通知重新创建应用程序时

MainActivity.onCreate() extras: null
MainActivity.onResume() extras: Bundle[{android:viewHierarchyState=Bundle[mParcelledData....
Run Code Online (Sandbox Code Playgroud)

最后一种情况不是我所期望的,不知何故通知意图附加只有在调用super.onCreate()之后才可用

关于如何实现1.和2.的任何想法?

巨人编辑: 这是通知代码,如您所见,有一个启动屏幕活动将意图转发给主要活动

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());
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

And*_*est 3

重写 Activity 提供的 onNewIntent(Intent Intent) 方法怎么样?

  1. Read saveInstanceState 可以为 null,并且 getIntent() 可以包含 GCM 的额外内容。

  2. 根据 Android 开发者的说法:

protected void onNewIntent(Intent意图)

如果活动在其包中将 launchMode 设置为“singleTop”,或者客户端在调用 startActivity(Intent) 时使用 FLAG_ACTIVITY_SINGLE_TOP 标志,则会调用此方法。在任何一种情况下,当活动在活动堆栈顶部重新启动而不是启动活动的新实例时,将使用用于重新启动的 Intent 在现有实例上调用 onNewIntent()它。

活动在收到新意图之前始终会暂停,因此您可以在此方法之后调用 onResume()。

请注意,getIntent() 仍然返回原始 Intent。您可以使用 setIntent(Intent) 将其更新为这个新的 Intent。