Activity life cycle methods : onPostResume significance
Asked Answered
I

5

26

Official documentation about Activity lists out 7 life cycle methods.

onPostResume() was not quoted as life cycle method.

But I feel that this method is important method.

During the life cycle, when an activity is visible from hidden to show state,

onRestart()
onStart()
onResume()
onPostResume()

have been invoked in order.

My code snippet:

package ravindra.projects.my_app_1;

import android.content.Intent;
import android.content.IntentFilter;
import android.os.PersistableBundle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import android.widget.TextView;


public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private EditText txtUserName;
    private EditText txtPassword;
    Button  loginButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d("Ravi","Main OnCreate");
        txtUserName=(EditText) findViewById(R.id.username);
        txtPassword=(EditText) findViewById(R.id.password);
        loginButton =  (Button)  findViewById(R.id.login);
        loginButton.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        Log.d("Ravi", "Login processing initiated");
        Intent intent = new Intent(this,LoginActivity.class);
        Bundle bundle = new Bundle();
        bundle.putString("userName",txtUserName.getText().toString());
        bundle.putString("password",txtPassword.getText().toString());
        intent.putExtras(bundle);
        startActivityForResult(intent,1);
       // IntentFilter
    }
    public void onActivityResult(int requestCode, int resultCode, Intent resIntent){
        Log.d("Ravi back result:", "start");
        String result = resIntent.getStringExtra("result");
        Log.d("Ravi back result:", result);
        TextView txtView = (TextView)findViewById(R.id.txtView);
        txtView.setText(result);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("Ravi","Main Start");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("Ravi","Main ReStart");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("Ravi","Main Pause");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("Ravi","Main Resume");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("Ravi","Main Stop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("Ravi","Main OnDestroy");
    }

    @Override
    protected void onPostResume() {
        super.onPostResume();
        Log.d("Ravi","Main PostResume");
    }

    @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
    }
}

Implementing onPostResume() by skipping below methods doesn't serve the purpose?

onRestart(), onStart(), onResume()

What are the advantages of implementing these three methods if I implement onPostResume() ?

onRestart(), onStart(), onResume()
Infighting answered 7/2, 2017 at 17:0 Comment(2)
There's lot to explain, its best explained here: commonsware.com/Android/Android-5.8-CC.pdf Page 303 of the book, it written by @Commonsware itself, this version is licensed under CC non commercial license .Selves
@OBX, cannot see onPostResume there.Occasion
O
36

As documented in http://web.archive.org/web/20170312114134/https://developer.android.com/reference/android/app/Activity.html

onPostResume : Called when activity resume is complete (after activity's {@link #onResume} has been called). Applications will generally not implement this method; it is intended for system classes to do final setup after application resume code has run.

It will do following things

  1. It will ensure that screen is visible to user and will do the final set up for activity.

  2. Remove any pending posts of messages with code 'what' that are in the message queue.

  3. Check all fragment gets resumed and Moves all Fragments managed by the controller's FragmentManager into the resume state.

  4. Execute any pending actions for the Fragments managed by the controller's FragmentManager.

If you check it life cycle vise it worked like below

  1. onResume() - Activity

  2. onResume() - Fragment check third point as explained above

  3. onPostResume() - Activity

Ossy answered 20/3, 2017 at 3:44 Comment(1)
Also I used the onPostResume() method in committing fragments in FragmentTransaction because that method are guaranteed to be called after the Activity has been restored to its original state and that way I will avoid the IllegalStateException to happen.Mediacy
D
6

onPostResume is mainly reserved for system actions which want to finish some kind of setup after any subclasses have finished resuming.

The two things it is good for, (which might make you feel it's important) are for doing actions after your nested fragments are also resumed and when the applications is guaranteed to be visible to the user (it may not yet be visible during onResume).

It can be a little confusing from the method names when looking at the Sources, but if you log the flow you'll see what happens is

  1. Activity Resumes
  2. Fragment Resumes
  3. onPostResume is called in Activity

I will add a word of caution for any future readers - if you use onPostResume to wait for your fragment, to call some get method (for example), then you have a bad, unreliable design. You should instead have a callback pattern from your fragment and have the fragment "send" the data back to the activity when it is ready

Dekow answered 17/3, 2017 at 16:15 Comment(2)
It may be that the application is visible to the user, but in my case the activity is not yet visible when onPostResume is called.Zane
What about the issues with the onSaveInstanceState? If you try to perform an operation in onResume, like to restore a dialog fragment then you need to commit a transaction and that can be dangerous because the state has not been restored yet.Miltiades
J
3

Before answering your question lets talk about onPostResume() According to android

onPostResume()

added in API level 1

void onPostResume ()

Called when activity resume is complete (after onResume() has been called). Applications will generally not implement this method; it is intended for system classes to do final setup after application resume code has run.

So as they said it is called once the activity is resumed. So if you want to do something after an activity is resumed you can use this method. But mostly we do all the stuff in onResume() like begin animations, open exclusive-access devices (such as the camera), etc. so once Activity is resumed onPostResumed() get called. So don't you think it differs from on resume? Because in onPostResume() according to os activity is already resumed.And for the onPause and onStop().They are different. They are when an activity is going into the background but has not (yet) been killed and Called when you are no longer visible to the user respectively. So they are different from onResume() and onPostResume().

Now before relying on onPostResume() you should read these two things As far as developers.android 1 - Applications will generally not implement this method; it is intended for system classes to do final setup after application resume code has run. (But we can use it for our purpose no matter what the intent of this). 2 - Check this link . He said that onPostResume() is not ALWAYS called . And his case was for fragments ( Of course they are over an activity man ). Here is the reply, The issue is completely resolved in API level 16 and support library rev 9. New method "FragmentActivity.onResumeFragments()" should be used.

So some of them having issues in relying on this method so it's up to you know.

Jacksonjacksonville answered 22/3, 2017 at 12:18 Comment(0)
K
0

onPostResume() was not quoted as life cycle method.

But I feel that this method is important method.

Most probably your feelings are wrong. And my answer on why it is so is a bit long and kind of abstract.

Abstract (but important) part

Typically various onPreXyz and onPostXyz (aka onBeforeXyz and onAfterXyz) methods are an attempt to make a base class open to extension by subclasses but still preserving some important behavior aspects. Assume that you are designing you own base class and you have a lifecycle event "Xyz" and your default handling behavior is following:

  1. Do some initialization before any other handling
  2. Do actual handling of event including customizable logic
  3. When all customizable handling is done do some finishing logic

Now assume that you are making something like Activity class - a base class with some bits of logic and the one that would be heavily inherited from, probably with deep hierarchies of inheritance. Now you should think of where (when) sub-classes logic will be exectuted regarding to logic in your base class. The important tricky part here is that you want your sub-classes to put their additional logic around step #2 (i.e. after #1 and before #3). You can't easily achieve this goal with simple virtual method because subclass can either put their logic after call to super which is after #3 or (rarely) before super call i.e. before #1. So what would you do? The Template method pattern comes to the rescue. You orgainze you code in a following way

class Activity {
    public final void performXyz(XyzEventData eventData) {
       onPreXyz(eventData);
       onXyz(eventData);
       onPostXyz(eventData);
    }

    protected void onPreXyz(XyzEventData eventData) {
       // put you logic from step #1 here
    }

    protected void onXyz(XyzEventData eventData) {
       // put you logic from step #2 here
    }

    protected void onPostXyz(XyzEventData eventData) {
       // put you logic from step #3 here
    }
}

So you have single external entry point performXyz that is called by the whatever context generates lifecycle events when the Xyz event happens and it dispatches the event internally to 3 different methods enforcing some sequence of execution. Typically you put all your code in your subclasses inside the "main" onXyz method unless you have a good reason to put it in one of the two others i.e. you expect your class to be subclassed as well and you want to ensure some execution order.

There are a few more points worth noting:

  1. Entry-point method performXyz is final (i.e. non-virtual). In this way you ensure that nobody can override it and break your execution order enforcement logic.

  2. The base class might even leave onPreXyz and onPostXyz methods empty by putting its steps #1 and #3 logic directly into performXyz. But if the designer of the base class expects possible deep inheritance hierarchies where some intermediate sub-class, that will be a base class for many other deeper subclasses (such as Layer supertype), might need the same execution order enforcement feature, it makes sense to provide such methods in the base class anyway.

  3. One of the onPreXyz or onPostXyz method might be omitted altogether if your case doesn't require 3-steps execution separation and 2-steps are enough. This is what often happens in Android: there are much more onPostXyz methods than onPreXyz but AsyncTask seems to be one noticible exception that feature both of them.

Closer look at Android (and onPostResume)

So after this long introduction, how Android uses this approach for onPostResume? If you look at the code at Activity.onPostResume you'll notice that it does very few things in the base class and the ones that are tightly related to UI stuff and probably expect all data-structures to be fully ready. This of course is not very surprising.

What is more interesting is how it is used in the subclasses. One of the very few overrides is at FragmentActivity from the v4 support library which provides backported "Fragments" features for old devices. FragmentActivity.onPostResume contains logic to resume child fragments. You may notice that in the standard Activity class similar logic to resume fragments is put directly into performResume method between mInstrumentation.callActivityOnResume(this); and onPostResume(); calls so it seems to be a part of step #3 in my earlier abstract description just put into the caller code. Obviously FragmentActivity can't put any new code to the Activity.performResume to ensure that it will be executed after activity's resume is done. Thus it puts the logic to the overridden FragmentActivity.onPostResume and in this way preserves the same semantics that fragments should be resumed after activity has already been resumed. Note also that the fact that this semantics explicitly preserved in both Activity and FragmentActivity classes suggests that this is the way it better should be. So if your code actually uses fragments, you'd better not put extensive logic into your onPostResume or something bad might happen (not sure what exactly).

Kirsch answered 15/3, 2017 at 23:28 Comment(3)
i really don't understand why this answer was downvoted. at least write your reason when downvoting. Downvoting only, doesn't help anyone. He/She puts effort to write an answer; you put effort to write a reason..Catto
What about the issues with the onSaveInstanceState? If you try to perform an operation in onResume, like to restore a dialog fragment then you need to commit a transaction and that can be dangerous because the state has not been restored yetMiltiades
@kingston, I don't think I understand your problem by this description. How onSaveInstanceState is related to onResume? It is called in a quite different part of the lifecycle. If you have some question, you should create a new question on the SO so everybody can answer rather than putting the same comment to answers on a vaguely related questions.Kirsch
M
0

After using log and overriding methods of activity lifecycle I came to following conclusion: This method can be very help ful in case you want to do execute any particular task in parent activity efter resuming a fragment (after loading a fragment) ....

I used/tried following code snippets to get to this conclusion :

in Parent activity :

//postResumemethod
 @Override
    protected void onPostResume() {
        super.onPostResume();
        Log.v("testPostResume","reached_postResume") ;

    }

In called Fragment :

//On ResumeMethod
 @Override
    public void onResume() {
        super.onResume();

        Log.v("testStartFragment","reached_Startfragment") ;
    }

This is my Log : V/testStartFragment: reached_Startfragment V/testPostResume: reached_postResume


We can clearly see the post resume is called after the onResume method of Fragment is executed . So after calling/loading fragment if you want to execute any code in activity(any task through acivity after loading fragment ) you can do that

I hope this clarifies the query

Misogynist answered 19/3, 2017 at 7:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.