Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reliability of the Activity Lifecycle (onPause to onDestory)

After years of trusting the lifecycle, i did a little digging. Now i am not amused.

I know and read a lot about that onStop is not guaranteed to be called etc.

I created a simple App with 2 Activites and a custom Application class. I put a Log.d() in every callback that i could find and played around on a Galaxy S2 with 4.1 on it. Activity A launches on start and in its onResume it starts Activity B. Activity B has a Button that creates a Nullpointer but otherwise it is doing nothing.

Now the things that worry/confuse me:

  • if i create a nullpointer on buttonclick, the app crashes and NO callback happens in neither activity

  • if i hit the powerbutton and turn off the screen, the activity will be restarted if the display mode (portrait or landscape) of the activity doesnt match the native orientation of the device. I do know that and how i could override it but IF it destroys and restarts my activity it calls onPause and isFinishing() returns false but the activity is being finished and restarted.

  • if above does not happen, only onPause is being called even though the app is no longer visible

  • starting another activity calls onPause in A, then creates B to onResume and then calls onStop of A. Now i am tracking my activites in the .App class and if i unregister A in onPause and register B in onResume, there will be a split millisecond where no activity is registered. If i wanted to shut down some service when no activity is there, it would happen all the time. But if i unregister it in onStop (so they would overlap) it would never be unregistered when the user hits the powerbutton and the service (or thread or whatever) keeps running and draining battery power.

I am working with android for quite some time now and i am trying to achieve a rather complex or lets say bulletproof design. But its almost impossible to keep track of what is happening to my activities.

  • powerdown has to be detected via Intent.ACTION_SCREEN_OFF but that happens when its already off. The only thing before that would be onPause.

  • homebutton... some combination of onUserInteraction and pause/stop

Its really hard to simply determine when my APP (not just one activity) is no longer being used and put in the background and when its just transitioning between activites or when its being shut down by the system. Because the .App class has NO callback for termination as onTerminate() is only used in emulator, so the docs say.

Maybe im just not seeing the forest through the trees... help would be appreciated!

like image 655
NikkyD Avatar asked Oct 22 '22 18:10

NikkyD


1 Answers

The Android lifecycle can be pretty confusing, and so far I've found only one way that lets you have a decent idea of what's going on around you.

You design your app in a way that you're always assuming you can be killed at any instant without callbacks like onDestroy() being called, because there is no guarantee that they will be called at all.

A simple way to check whether an Activity is going into the background because another one of your Activities is coming to the front is by using a simple flag:

boolean movingInApp = false;
....
movingInApp = true;
Intent intent...
.....
public void onPause() {
    if(movingInApp) {
        //Called because we're moving to another Activity in our own app
    }
}

public void onResume() {
    movingInApp = false;

}

By setting the value of movingInApp to true before launching any intent etc, you can keep track of why onPause() is being called. Remember to set it to false again later in your onResume() method. If the system makes your app go to the background, this will be false, and you know that your app was moved to the background by someone else, and not you.

As for nothing being called when an exception occurs, Android simply kills your entire App process whenever there is an uncaught exception. Your app simply stops running, like when you force quit a program on your computer. The system kills is completely and without any warning. No more code is executed at all.

like image 67
Raghav Sood Avatar answered Nov 03 '22 18:11

Raghav Sood