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

时间:2014-08-26 23:55:37

标签: android android-intent android-fragments notifications activity-lifecycle

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

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

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

  3. 我的方法依赖于检查我在构建启动主活动的通知时添加的意图额外内容,为了简洁起见,部分代码未显示但是我总是在意图中添加一些额外内容,总是< /强>

    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的任何想法。?

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

    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);
    }
    

1 个答案:

答案 0 :(得分:2)

如何覆盖Activity提供的onNewIntent(Intent intent)方法?

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

  2. According to Android Developers:

  3.   

    protected void onNewIntent(Intent intent)

         

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

         

    在收到新意图之前,活动将始终暂停,所以   你可以指望在这个方法之后调用onResume()。

         

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