In android, life-cycle of each application is mostly controled by its Activities. Each Activity has its own left-cycle, you can get detailed information from this link.
Mostly, these Activities interact with user while those are in foreground. Android will put the activity to background in following cases:
1. If the activity starts another activity
2. or in any interrupts, like as, got a incoming call or pressing home button etc.
And if finish() called or back button pressed, it will stop the activity.
Here the problem is with the activities which are brought to background. In one point of time android will stop and remove these activities from the activity stack. There is no guarantee as android will call any call back method before it stops those activities.
Only guaranteed call back is onPause, which will be called while an activity go to background. So, It is recommended to persist state or necessary data and release all allocate resources (Files may have opened in Native or allocated memory etc.)
If you look at the following diagram, you will understand all onPuase calls.
But, in some case it is more expensive to persist the state of application data and releasing resources in every onPause calls. Actually we don’t need to do this if user moving around inside our application. In the above diagram, in each onPause call if it with green pop-up, then we don’t need to persist or release. In other cases we need.
Additionally android provide isFinishing() API to check whether the activity is finishing or not. But that is not clearly provide an idea when to do the persistence and not. We need another flag to indicate while an activity pauses due an new child activity started from that activity.
If i put this into a table:
| Main Activity | Child Activity |
Start Activity | don’t persist | don’t persist |
call finish() or back pressed | persist | don’t persist |
Home button pressed, got an incoming call | persist | persist |
Let check the following class to track for staring child activity state.
import android.app.Activity;
import android.content.Intent;
public class TscaActicity extends Activity {
private boolean mStartingChildActivity;
public void setStartingChildActivity(boolean startingChildActivity) {
mStartingChildActivity = startingChildActivity;
}
public boolean isStartingChildActivity() {
return mStartingChildActivity;
}
@Override
protected void onResume() {
setStartingChildActivity(false);
super.onResume();
}
@Override
public void startActivityForResult(Intent intent, int requestCode) {
setStartingChildActivity(true);
super.startActivityForResult(intent, requestCode);
}
/... other start * call should flow the same patter ../
}
Let put both isFinishing() and isStartingChildActivity() together in a table:
| Main | Main | Child | Child |
| isFinishing() | isStarting ChildActivity() | isFinishing() | isStarting ChildActivity() |
Start Activity | false | true | false | true |
call finish() or back pressed | true | false | true | false |
Home button pressed, got an incoming call | false | false | false | false |
So finally, we need to write a Main Activity and Child Activity as follows:
import com.muvee.studio.activity.TscaActicity;
public class MainActivity extends TscaActicity {
@Override
protected void onPause() {
if(!isStartingChildActivity()){
//persist
//release
}
super.onPause();
}
}
import com.muvee.studio.activity.TscaActicity;
public class ChildActivity extends TscaActicity {
@Override
protected void onPause() {
if(!isFinishing() && !isStartingChildActivity()){
//persist
//release
}
super.onPause();
}
}
No comments:
Post a Comment