17

My end-goal is to have an application that runs a block of code when it (the application, not the activity) is opened up after being left ( back from home screen, etc... )

According to the Activity Lifecycle, this should be the onRestart() event on a per activity basis ( at least how I interpret it )

Both onRestart() and onResume() are being called whether I am returning to the Activity within the application (back button) AND when the app is called back up.

Given this diagram enter image description here

I am interpreting it this way:

  • RED = movement between activities within the application
  • BLUE = moving to an activity outside the Application

Is my understanding incorrect?

EDIT (Clarifying specific use case)

I'm attempting to use onRestart() to replicate some security logic (PIN Validation) found in onCreate(), but it's being called even when I press the back button inside the application...

Community
  • 1
  • 1
jondavidjohn
  • 61,812
  • 21
  • 118
  • 158
  • I somewhat understand what you are saying... I would recomend you implement all the Activity functions and output Logs to the Logcat and see how it behaves according to the different scenarios you are looking to get more understanding. – Jona Jun 28 '11 at 16:46
  • 8
    +1 for hand drawn circles – George Powell Apr 11 '13 at 11:20
  • @GeorgePowell Huh, so practicing drawing all those Amoeboid pseudopodia in biology classes was not a complete waste of time after all... :P – varun Mar 04 '19 at 09:38

5 Answers5

4

My observation is that its hard to tie the lifecycle events to user behavior on the device or emulator. Where your app is paused, if the device needs memory or wants to recover resources, it will terminate the activity, causing onCreate to be called. There is just too many scenarios to build an adequate state machine to tell yourself "how" or "why" your activity was terminated.

The only way I've found to manage this is to create a service to hold the application state and manually manage the state. The problem is trying to use the Activity state to manage the application state. The Activity design seems to have limitations that just make it a poor choice for achieving the goal you've stated.

Nick Campion
  • 10,479
  • 3
  • 44
  • 58
1

Here is how to do this:-

  1. Have a base activity that all your activities are derived from.

  2. Add in to the base activity:-

    int nAppState;
    
    protected override void OnCreate(Bundle bundle)
    {
            base.OnCreate(bundle);
            nAppState = 0;
            .
            .
    }
    protected override void OnStop()
    {
            AppState();
            base.OnStop();
    }
    public static int IMPORTANCE_BACKGROUND = 400;
    
    protected override void AppState()
    {
            ActivityManager am = (ActivityManager)GetSystemService(Context.ActivityService);
            IList<ActivityManager.RunningAppProcessInfo> list2 = am.RunningAppProcesses;
            foreach (ActivityManager.RunningAppProcessInfo ti in list2)
            {
                    if (ti.ProcessName.ToLower() == "com.mycompany.myapp")
                    {
                            nAppState = ti.Importance;
                            break;
                    }
            }
    }
    protected override void OnRestart()
    {
            base.OnRestart();
            if (nAppState == IMPORTANCE_BACKGROUND)
            {
                    // Show a log in screen
                    RunOnUiThread(delegate { StartActivity(new Intent(this, typeof(LoginAppearActivity))); });
                    nAppState = 0;
            }
    }
    
  3. Please note that this is in Mono C#, it will be the same code for Java, I'll leave it up to you to convert it!!

1

That would be because when unless your are using Fragments each "screen" in your application is a new activity, when you click the back button it restarts the activity of the page before it.

If I am understanding what you want to do correctly you want to put your code on onCreate, not onRestart.

SEE COMMENT THREAD FOR ANSWER

jondavidjohn
  • 61,812
  • 21
  • 118
  • 158
Peter-W
  • 737
  • 2
  • 9
  • 14
  • onCreate is only called the first time the application is opened. – jondavidjohn Jun 28 '11 at 16:48
  • 4
    No, it is called every time an Activity is created. If your application has multiple Activities then onCreate is called every time one is created, even if the Application has been running the whole time. – Peter-W Jun 28 '11 at 16:55
  • 1
    That is a false statement jondavidjohn. The left side of the diagram shows that activity termination (explicit or memory caused) will cause onCreate to be called. – Nick Campion Jun 28 '11 at 16:56
  • Correct, I was loose with my language, I know it is called on a per Activity basis, I was pointing out that it is not called when the Activity is Resumed, and yes if it is "killed" it will have to be "created" again. – jondavidjohn Jun 28 '11 at 16:58
  • @Peter-W back to your original Assertion that the application is "restarting" the previous activity. In my stated understanding of the lifecycle above I say that the event you're describing should be `onResume()` not `onRestart()` because you're moving between activities inside your application... – jondavidjohn Jun 28 '11 at 17:03
  • 1
    Nick's answer is best since you can not guarantee that the Activity will be killed when it goes to the background. I suppose it might be possible for you to manually kill it before it goes to the background in the onStop method. This should force it to take the left path to onCreate, not the right one to onRestart/onResume. EDIT: In regards to your second post, no. onRestart will be called before onResume even within your application. – Peter-W Jun 28 '11 at 17:04
  • @Peter-W right, that is really the answer to my question, that my understanding above is actually **incorrect**, even within the app activities will always be stopped and restarted, not paused. – jondavidjohn Jun 28 '11 at 17:31
0

You have an option to avoid the previous activity by avoiding/removing the activity to come in Stack by setting some flag before calling the startActivity(intent):

intent.setFlags(i.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY);

This will avoid the present activity to get called on back press. Alternatively you can also ovverride the onBackPressed() method of the current activity.

Saty
  • 1,068
  • 11
  • 24
0

Yes, your assertions for red and blue are correct.

However, note the alternate pathway from onPause() and onStop(). Process being killed for memory reasons is a) out of your control and b) imperceptible to you if you only use onRestart() to detect "coming back" to the activity.

yep
  • 1,263
  • 1
  • 9
  • 13
  • Right, which is acceptable in my case because I'm attempting to use onRestart() to replicate some security logic (PIN Validation) found in onCreate(), but it's being called even when I press the back button inside the application... – jondavidjohn Jun 28 '11 at 16:44