4

I have an already visible activity (so onStart has run), I pull down the notifications bar, click on a notification associated with a pending intent for said activity. 1) onPause is called. Note that onStop is NOT called 2) onCreate for a new instance of the activity is called then onStart, etc...

As suggested I've tried singleTask and singleInstance but they don't prevent a new instance being created after onPause is called. Interestingly, this only happens when the activity is visible and I click its notification. If it's already been stopped, Android uses the old instance. Perhaps I need to tweak how the PendingIntent is generated...

Creos
  • 2,445
  • 3
  • 27
  • 45
  • Okay, investigate carefully and let us know what happens in the end. Best of luck. – ZakiMak Jan 25 '15 at 15:45
  • Someone else had a similar problem http://stackoverflow.com/questions/10104110/pending-intent-always-make-new-activity – Creos Jan 25 '15 at 16:31
  • This makes no sense. Did you initially launch your app from the installer screen, or directly from an IDE (Eclipse, IntelliJ, Android Studio)? If so, you are probably seeing this nasty Android bug: http://stackoverflow.com/a/16447508/769265 – David Wasser Jan 26 '15 at 17:34

1 Answers1

4

I think it's possible that a new Activity is created in the stack when you run the Pending Intent. Configure your activity so that it does not create a new Activity via launchMode set to singleTask or singleInstance.

Here is an example of setup I have used for an activity:

<activity
            android:name="com.zakimak.HomeScreenActivity"
            android:screenOrientation="portrait"
            android:label="@string/app_name"
            android:launchMode="singleTask" />

Then building the pending intent is as follows:

    Intent resultIntent = new Intent(context, HomeScreenActivity.class);
    // The request code 24601  uniquely identifies the notification generated 
    // by the application. As an application may generate several having        
    //different codes to identify each. CAUTION: It's value should be greater than 0 
    //.i.e. RESULT_FIRST_USER+

    PendingIntent resultPendingIntent = PendingIntent.getActivity(context,
            24601, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    Notification notification = new NotificationCompat.Builder(context)
            .setSmallIcon(R.drawable.ic_launcher).setContentTitle("Title")
            .setContentText("Bla bla").setOngoing(true)
            .setTicker("Bla bla is running").setAutoCancel(false)
            .setContentIntent(resultPendingIntent).build();

Step1: I start the application and show HomeScreenActivity. Then I drag the notification bar and click the notification. It opens the Activity and the following callback methods are called : onPause and then onResume. onPause is called because activity could still be visible under the drawer.

Step2: I start the application and show HomeScreenActivity and press Home or launch another activity, then onStop is called. Then I drag the notification bar and click the notification. It opens the Activity and the following callback methods are called : onStart and then onResume.

In both of the cases onCreate is called only once, when the Activity is launched for the first iteration. It was tested in emulator.

In some cases when your device is in heavy load or trying to save power, it's possible the Android might kill the process.

ZakiMak
  • 2,072
  • 2
  • 17
  • 26
  • thanks a lot, i've updated the question, didn't seem to help. perhaps i'm doing something stupid, not sure... – Creos Jan 25 '15 at 16:01
  • I have provided an update for you. Please check the updated answer. – ZakiMak Jan 25 '15 at 18:35
  • what is the code 24601, how did you come up with that number? that's supposed to be some private code you used to communicate and not part the API constants, just curious, thx. – Creos Jan 25 '15 at 21:13
  • i compared your solution to mine and the only difference was that i was passing 0 where you are passing 24601. I tried now 1 and it also works. I've no idea why that makes a difference but it does. – Creos Jan 25 '15 at 22:24
  • To answer, my own question, I believe the answer lies in the constants defined in Activity.java. A PendingIntent is a token to an invocation of startActivity (and all its variants), hence the meaning of the codes must be the same. I will accept your answer, but can you please also add a comment that the code passed must be Activity.RESULT_USER and higher [continued] – Creos Jan 26 '15 at 00:27
  • Activity.java /** Standard activity result: operation canceled. */ public static final int RESULT_CANCELED = 0; /** Standard activity result: operation succeeded. */ public static final int RESULT_OK = -1; /** Start of user-defined activity results. */ public static final int RESULT_FIRST_USER = 1; – Creos Jan 26 '15 at 00:28
  • I believe its a number private to your own application that uniquely identifies the Notification from other notifications your application may generate. It is a requestCode and should be greater than 0. – ZakiMak Jan 26 '15 at 03:50
  • yup since 0 is reserved for "cancelled" which kills and restarts the activity. Can you just add that "caution" statement to use RESULT_FIRST_USER+) and i'll accept. i think it's a key part of the solution and many might not read the comments thx – Creos Jan 26 '15 at 03:53
  • In general it is a very bad idea to use special launch modes `singleTask` and `singleInstance`. They will cause you more problems than they solve. If you are resorting to this it means you have a problem somewhere else and this is just a hack to work around that. You need to find and fix the real problem, otherwise you will have more headaches later on. – David Wasser Jan 26 '15 at 17:36