9

My application calls a few web services when it is freshly launched. I would also like to call these web services if the user launches the app (which was running in the background) and resumes. I've looked into all the methods fired when apps are launched and when activities are in focus. onStart(), onResume(), onRestart() etc....

I thought onRestart would be a good bet to make my web service calls and update my view, problem is if I go from activity A (the one making the calls) to activity B and hit the back button, activity A will fire onRestart() and call the web services. I don't want this to happen everytime I go back to my main screen from some activity in my app. I only want the services to be called if my app activity A is brought into focus from the outside. Are their any other events I should be aware of that could help me? If I hit the home button and then hit my app icon it should update, but not if I click something on my main screen, opening a new activity and then hit the back button.

Hope the question makes sense.

Thanks.

PaulG
  • 6,920
  • 12
  • 54
  • 98
  • When you say "if the user launches the app (which was running in the background)", how is the app went to background in the first place, by pressing back button or home button? – havexz Dec 05 '11 at 18:41
  • HOME button, should have mentioned that. – PaulG Dec 05 '11 at 18:43

3 Answers3

8

According to the Activity lifecycle, onRestart will be called before onResume. So if you put your web calls in onResume, it will be called when the activity first starts and any time it resumes. onRestart is only called when the user navigates back to that activity. So you can have a boolean in your activity (ex. boolean isActivityRestarting) that is set to false, then set to true in onRestart. If it's true when onResume is hit, then don't do your web calls.

Example code:

public void onRestart() {
    isActivityRestarting = true;
}

public void onResume() {
    if (!isActivityRestarting) {
        executeWebCalls();
    }

    isActivityRestarting = false;
}
Jason Robinson
  • 31,005
  • 19
  • 77
  • 131
  • 2
    Thanks for the response. This won't work. I'm currently printing every call to onResume() onStart() onRestart() onStop() onPause() etc from all of my activites to the log. This is my initial problem of, if I click something from my MainScreen (the web service calling screen) and open activity B, then hit BACK it will fire the following methods: onRestart() onStart() onResume() in that order. So with the logic in your answer it would call the web services either way. – PaulG Dec 05 '11 at 19:16
  • I think you misunderstand. By the time you get to onResume(), you already know whether the activity is restarting or not. I edited my answer to show code. – Jason Robinson Dec 05 '11 at 19:17
  • What about if the user exits my app with the HOME button? When he launches again it will call onRestart() onStart() onResume() in that order, so I DO want it to call the web services when onRestart happens, just not when it's coming from a BACK button hit. – PaulG Dec 05 '11 at 19:23
  • Because of my problem in my last comment I decided to try setting a "shouldUpdate" flag to false in the onBackPressed event of my activityB, it doesn't work because I have to set this flag to true at some point for the web services to be called but have not figured out where to do this yet. – PaulG Dec 05 '11 at 19:27
  • in whichever life cycle method you're using for your web calls, set the shouldUpdate flag to true at the end. That will "reset" that boolean. Initialize the boolean to true, so it's only false when onBackPressed is triggered. – Jason Robinson Dec 05 '11 at 19:32
  • Right now my web services are call in OnCreate() of my MainActivity. So I set the boolean to true in OnCreate(), but when I go to activityB and hit back it's set to false, which is what I want BUT when will it ever get set to true again?? This is my dilemma, knowing when to set it to true. – PaulG Dec 05 '11 at 19:36
  • Well first off, you need to move your web calls from onCreate. I'd recommend moving it to onResume. The very last line of your onResume method, set shouldUpdate to true. – Jason Robinson Dec 05 '11 at 19:47
  • When will I set shouldUpdate back to true once it's been set to false by the BACK button? I've thought of doing it that way as well but like I said I don't know when to set the flag back to true so that it can actually get new data. If I could detect a HOME button press (which isn't legal on Android) I could set it to true there and have it call my web services when I open the app, but can't. I've tried many things – PaulG Dec 05 '11 at 19:54
  • 1
    Read the last sentence of my previous comment. – Jason Robinson Dec 05 '11 at 20:05
4

Well onCreate is your best bet, but with some caveat. (main screen here is the screen which calls webservice)

  • If the user presses BACK button on the main screen, onCreate will be called.
  • If the user presses BACK button on the other screen and comes back to the main screend, onCreate wont be called.
  • If the user exits the main screen using HOME button, and comes back by long pressing HOME button and choosing your app, onCreate is not called.

So far so good, here is the catch.

  • If the user presses HOME button to exit and then goes to the launcher icon, the onCreate is not called. Theoretically it is consistent behavior but might look odd as user might be thinking that he/she is launching an app from start forgetting how he/she exited initially.

To your ans, onCreate is the way to go with slight checks.

Soln if using onStart or onRestart:

One check which you can do is store the time stamp in your Shared Preferences, which corresponds to when you called the web services. Now when user exited (whether by HOME or BACK key) and come back you can check the time and compare it against the stored time. If the difference is high just make the webservice call. To make this work you have to use onStart or onRestart.

havexz
  • 9,550
  • 2
  • 33
  • 29
  • Exactly my problem. I do my web service calls in OnCreate() right now, but like you said OnCreate won't get called when I resume my application. I've been looking into these "slight checks" for about 2 hours now but have not come up with anything. We can't catch a HOME button press for obvious reasons, I'm close to the end of my rope. – PaulG Dec 05 '11 at 19:04
  • The time difference could still be high if the user doesn't exit the app. And both onStart() and onRestart() will still get called if I hit BACK to the mainScreen. – PaulG Dec 05 '11 at 19:30
  • 2
    Tell me one thing, does it harm in any way if the user is on some screen and comes back after a long time and we make the web service call, as local data might be stale by this time? So idea instead of having life-cycle based calls we have time elapsed based calls – havexz Dec 05 '11 at 19:39
  • You're right it probably wouldn't harm the user since their due for new data anyhow. – PaulG Dec 05 '11 at 19:42
1

Since this is normal behavior (see http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle) I would recommend not trying to work against it, but rather work with the lifecycle methods.

Your app is being brought to focus from the outside, whether from this other activity or otherwise.

Perhaps you should call the services in onCreate?

skynet
  • 9,898
  • 5
  • 43
  • 52
  • OnCreate is not called when an app is resumed. Thanks anyways – PaulG Dec 05 '11 at 19:01
  • Well, you don't always want to call it if your app is resumed, otherwise you would use `onResume` or `onStart`, right? – skynet Dec 05 '11 at 19:04
  • Ideally yes, but onResume() and onStart() are BOTH called whenever I hit the back button from activity B back to activity A (mainScreen). I don't want to call the web services everytime I hit back to the main screen. – PaulG Dec 05 '11 at 19:05
  • When do you want the web services to be called? Could you edit your question defining those cases? If you only want to do it once per activity life then go with `onCreate` – skynet Dec 05 '11 at 19:06
  • Basically I want the web services to be called whenever the user hits the Application Icon. Two things can happen here. 1) The app is launched and onCreate is called, thus calling the web services 2) The app is launched but since it was already running in the background (the user probably hit the home button his previous session) onCreate is not called and no web services are called. – PaulG Dec 05 '11 at 19:09
  • Well, one option you have is to use a different `launchMode` for your activity. See http://developer.android.com/guide/topics/manifest/activity-element.html#lmode. Notice that the last two are not recommended for general use. You might be able to use the second one (`singleTop`) and then call your web service in `onNewIntent()` – skynet Dec 05 '11 at 19:14
  • Thanks Craigy, sounds great but I'll look into that as a last resort, I'm sure there's an easier way to accomplish this. – PaulG Dec 05 '11 at 19:39