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()
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
It will ensure that screen is visible to user and will do the final
set up for activity.
Remove any pending posts of messages with code 'what' that are in
the
message queue.
Check all fragment gets resumed and Moves all Fragments managed by
the controller's FragmentManager into the resume state.
Execute any pending actions for the Fragments managed by the
controller's FragmentManager.
If you check it life cycle vise it worked like below
onResume() - Activity
onResume() - Fragment check third point as explained above
onPostResume() - Activity
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
Activity Resumes
Fragment Resumes
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
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.
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:
Do some initialization before any other handling
Do actual handling of event including customizable logic
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:
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.
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.
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).
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
Related
When I was reading this link https://developer.android.com/guide/components/services#LifecycleCallbacks,I came across this statement
Note: Unlike the activity lifecycle callback methods, you are not required to call the superclass implementation of these callback methods.
Can anyone explain why it is not required to call superclass and on what scenario we can add superclass implementation?
Thanks
In the activity lifecycle the callbacks are made because we need to run the existing code on those methods of the Activity class.
For example
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
// your code
}
In this method we say the compiler to not only run our code but also the existing code in the onCreate method of the Activity class. The existing code takes care of assigning the context to the activity, setting the actionBar etc. If you wanna know more about what the existing onCreate method code does, you can navigate through that method in the Activity class.
But in the case of Service we need not run the existing code ( of course there are no existing code in those methods ) and the system itself takes care of what to do and only notifies us about what lifecycle the service is going through so that we can code according to the lifecycle our service is in.
For example
#Override
public void onDestroy() {
// You can make a toast here to notify the user that the service has ended
}
This method in the Service class notifies that the service is being destroyed. You can navigate through this method in the Service class and see no code has been written on that method. So we can conclude that the method is only notifying us about the destroying of the service.
But you can still make a super call on the method, Like below
#Override
public void onDestroy() {
super.onDestroy();
}
But we have no changes in the running of the code since the onDestroy method in the super class is empty. More precisely we don't need the existing code (in this case it's empty) to what we expect that to do.
For your last question,
You should implement a super call when you wanna run the existing code. If you just wanna know if the method is called and you don't wanna run the existing code but only your code on the subclass you should not implement a super call
Using a retained fragment to host asynchronous tasks is not a new idea (see Alex Lockwood's excellent blog post on the topic)
But after using this I've come up against issues when delivering content back to my activity from the AsyncTask callbacks. Specifically, I found that trying to dismiss a dialog could result in an IllegalStateException. Again, an explanation for this can be found in another blog post by Alex Lockwood. Specifically, this section explains what is going on:
Avoid performing transactions inside asynchronous callback methods.
This includes commonly used methods such as AsyncTask#onPostExecute()
and LoaderManager.LoaderCallbacks#onLoadFinished(). The problem with
performing transactions in these methods is that they have no
knowledge of the current state of the Activity lifecycle when they are
called. For example, consider the following sequence of events:
An activity executes an AsyncTask.
The user presses the "Home" key,
causing the activity's onSaveInstanceState() and onStop() methods to
be called.
The AsyncTask completes and onPostExecute() is called,
unaware that the Activity has since been stopped.
A FragmentTransaction is committed inside the onPostExecute() method,
causing an exception to be thrown.
However, it seems to me that this is part of a wider problem, it just happens that the fragment manager throws an exception to make you aware of it. In general, any change you make to the UI after onSaveInstanceState() will be lost. So the advice
Avoid performing transactions inside asynchronous callback methods.
Actually should be:
Avoid performing UI updates inside asynchronous callback methods.
Questions:
If using this pattern, should you therefore cancel your task, preventing callbacks in onSaveInstanceState() if not rotating?
Like so:
#Override
public void onSaveInstanceState(Bundle outState)
{
if (!isChangingConfigurations())
{
//if we aren't rotating, we need to lose interest in the ongoing task and cancel it
mRetainedFragment.cancelOnGoingTask();
}
super.onSaveInstanceState(outState);
}
Should you even bother using retained fragments at all for retaining ongoing tasks? Will it be more effective to always mark something in your model about an ongoing request? Or do something like RoboSpice where you can re-connect to an ongoing task if it is pending. To get a similar behaviour to the retained fragment, you'd have to cancel a task if you were stopping for reasons other than a config change.
Continuing from the first question: Even during a config change, you should not be making any UI updates after onSaveInstanceState() so should you actually do something like this:
Rough code:
#Override
public void onSaveInstanceState(Bundle outState)
{
if (!isChangingConfigurations())
{
//if we aren't rotating, we need to lose interest in the ongoing task and cancel it
mRetainedFragment.cancelOnGoingTask();
}
else
{
mRetainedFragment.beginCachingAsyncResponses();
}
super.onSaveInstanceState(outState);
}
#Override
public void onRestoreInstanceState(Bundle inState)
{
super.onRestoreInstanceState(inState);
if (inState != null)
{
mRetainedFragment.stopCachingAndDeliverAsyncResponses();
}
}
The beginCachingAsyncResponses() would do something like the PauseHandler seen here
From a developer's point of view, avoiding NPEs' in a live app is the first order of business. To methods like onPostExecute() of AsyncTask and onResume() & onError() in a Volley Request, add:
Activity = getActivity();
if(activity != null && if(isAdded())){
// proceed ...
}
Inside an Activity it should be
if(this != null){
// proceed ...
}
This is inelegant. And inefficient, because the work on other thread continues unabated. But this will let the app dodge NPEs'. Besides this, there is the calling of various cancel() methods in onPause(), onStop() and onDestroy().
Now coming to the more general problem of configuration changes and app exits. I've read that AsyncTasks and Volley Requests should only be performed from Services and not Activitys, because Services continue to run even if the user "exits" the app.
So I ended up digging around a bit on this myself and came up with quite a nice answer.
Although not documented to do so, activity state changes are performed in synchronous blocks. That is, once a config change starts, the UI thread will be busy all the way from onPause to onResume. Therefore it's unnecessary to have anything like beginCachingAsyncResponses as I had in my question as it would be impossible to jump onto the main thread after a config change started.
You can see this is true by scanning the source: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.0.2_r1/android/app/ActivityThread.java#3886 looking at this, it looks like onSaveInstancestate is done sequentially with handleDestroyActivity ... And so it would be impossible to update the UI an have it lost during a config change.
So this should be sufficient:
#Override
public void onSaveInstanceState(Bundle outState)
{
if (!isChangingConfigurations())
{
//if we aren't rotating, we need to lose interest in the ongoing task and cancel it
mRetainedFragment.cancelOnGoingTask();
}
super.onSaveInstanceState(outState);
}
From the retained fragment it's crucial to access the activity from the main thread:
public void onSomeAsyncNetworkIOResult(Result r)
{
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable()
{
//If we were to call getActivity here, it might be destroyed by the time we hit the main thread
#Override
public void run()
{
//Now we are running on the UI thread, we cannot be part-way through a config change
// It's crucial to call getActivity from the main thread as it might change otherwise
((MyActivity)getActivity()).handleResultInTheUI(r);
}
};
mainHandler.post(myRunnable);
return;
}
I'am having troubles with Googles MapView Activity.
The reason for my problem:
My application relies on many asynchronous events. When I start an Activity containing the Map, I've a template mechanism which adds and initializes the Map and relays all activity callbacks like onCreate(), onResume() to the map. All works fine!
But when this activity is restored from background my template mechanism is not yet ready to create the dynamic layout in onCreate(), hence I can't relay the lifecycle callbacks which are needed for the Map. In worst case, the Map is created after onResume().
This simplified code is for understanding the issue:
public class MapActivity{
List<Templates> templates;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (app.isInit())) {
initActivity();
}
templates.onCreate();
}
// init after templates are loaded
private void initActivity() {
templates = templateEngine.renderSomeTemplates()
}
#Override
protected void onResume() {
super.onResume();
templates.onResume()
}
public void onEventMainThread(InitAppEvent event) {
initActivity()
}
}
So my question.
Is there any way to add a google MapView programmatically during runtime without passing onCreate() and so on to it or do some lazy init?
Ok, I figured it out.
Apparently it's impossible to live without the callbacks as described in the docs:
http://developer.android.com/reference/com/google/android/gms/maps/MapView.html
So I found a trick to force my activity to start all over again, as soon as my dependencies (templates) are ready.
If anyone is looking for a neat way to restart an activity: there is recreate()
http://developer.android.com/reference/android/app/Activity.html#recreate()
It basically finishes the activity and repeats the normal lifecycle from the beginning.
Yes its is possible, take a look at the samples in the SDK
I'm working on my 1st Android app and wondering how to handle activation/deactivation/starting/stopping globally, not on Activity level.
This great article shows states transition for Activities:
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
Is there something similar for Application states?
For example at iOS and Windows Phone app there is clear app states separated from activities (views, controllers, whatever).
I'm asking because I want to perform certain operations only once per app loading/exiting not with every activity starting/stopping
The answer is There is Simply No Direct method to do this
rather than in Application Class you can catch these events
#Override
public void onLowMemory()
{
super.onLowMemory();
}
#Override
public void onTerminate()
{
super.onTerminate();
}
So you will have to handle it in all the Activities you will be having
the following methods
onResume()
onStart()
onRestart()
onPause()
onDestroy()
You will have to implement in all Activity to handle for all application
A suggesstion
You can have some Variable in Application class to save application state
say create a variable like
public static boolean isPaused;
and set it from all activity on state change
The question you're asking is applicable for iOS and Windows but not really for Android.
Android doesn't really have a concept of an application as an object, although there's an Application class. Instead, an app is a loose collection of Activities. There are many good reasons for this state of affairs; for example, it supports fast app switching and easy interaction between Activities of different apps.
The best way to coordinate your "app" so that one Activity doesn't try to do something that's already been done is to use SharedPreferences to store app state. Nearly every other way of doing it is less preferred. Even if the system kills off your entire app, SharedPreferences will maintain the current state. The Application object won't.
Also, Android is based on pausing and resuming. An Activity or activities are created, pause, and resume. They may be destroyed, but that's an extreme case. A corollary to this is that apps should not have an exit button; there's no need for one. I sometimes see apps that have one, but what they're really trying to do is shut down a background Service or process. The best way to do that is to have an affordance that says "Sleep" or similar.
Have all activities inherit from the same hierarchy and put whatever you want in OnCreate, OnPause, OnResume, OnStop, OnDestroy and call the super where applicable.
Example
Parent
IamTheParentActivity : Activity
protected void onCreate()
{
setApplicationState(ApplicationState.Running);
}
protected void onPause()
{
setApplicationState(ApplicationState.Paused);
}
private void setApplicationState(Enum ApplicationState)
{
//Some Application Level Variable
Application.State = ApplicationState
}
Children
IamTheChild : IamTheParentActivity
protected void override onCreate()
{
base.OnCreate;
do other stuff
}
When I write my activities on android, I have to override a lot of "lifecycle" methods, such as onCreate, onActivityResult:
class MyAcitivity extends Activity {
#Override
public void onCreate(...) {}
#Override
public void onStart(...) {}
#Override
public void onActivityResult(...) {}
#Overide
public void onBackPressed(...) {}
}
I don't like this, because I found my logical code are split to everywhere in my class. I do some operation in this method, but I have to handle the result in another method.
Is it the only way to design Activity like this? Is there any other solution can let me do the same without overriding methods from super classes?
Update
I do some operation in this method, but I have to handle the result in another method.
For example:
public void onCreate(...) {
startActivityForResult(new Intent(this, AnotherAcitity.class), INTENT_ANOTHER);
}
public void onActivityResult(...) {
if(requestCode == INTENT_ANOTHER) {
// do something
}
}
Update again
I know how to use these lifecycle methods, what I'm thinking is the "design". Is there any different way to design android (in theory) without "overriding lifecycle methods" to write activities. Does ios and win8 on mobiles use the same design as android? If I develop an ios or win8 application, do I have to override all kinds of lifecycle methods as I do on android?
You only need to override the methods you're using in your Activity. So if your activity simple displays a help page that has already been populated in the XML, you only have to override onCreate() and call setContentView().
In general, if your overriden method is like:
public void myOverridenMethod() {
super.myOverridenMethod();
}
That is to say, it contains nothing but a super call, you need not override it.
In the example you provided, you must override the appropriate lifecycle methods as the calling of these is beyond your control, unless you're willing to develop a custom ROM for your device(s).
EDIT
The Android lifecycle methods are called by the system at specific predefined points in your app's life.
You cannot design an Activity in a different way, as if you do Android has no idea which method does what. However, it knows exactly when to call which method in the Android lifecycle. By using your own methods instead of these, you have an app which Android cannot interact with.
Additionally, many lifecycle methods like onCreate() etc. help setup the initial bits of your app (like getting it a Context).
iOS and Windows Phone and BlackBerry have similar lifecycle methods, but they don't always have an exact Android equivalent, as all are different platforms and handle their apps differently.
This is just a generic framework pattern, framework doesn't depend on you, just notifies you, all your actions are optional for framework. It's called Inversion of Control.
This is just opposite to the direct style of programming where you decide everything about the Application, and give commands to framework.
Google developers designed Activity class, and Android only works through them. Android calls these methods whenever it pleases. Android does not care what you do in those methods, it just cares to notify you of the life cycle events.
Since everything is optional, you just have to fill in the places you are really interested in. An empty Activity runs just fine.
public class MyActivity extends Activity { }
If anything additional needs to be done, just add the code at correct place:
public class MyActivity extends Activity {
#Override
public void onCreate(...) {
//---whatever you want to do in this stage of life cycle----
}
}
You dont necessarily need to override all methods of life cycle of an activty. They all are for a specified purpose
onCreate() :
Called when the activity is first created. This is where you should do
all of your normal static set up: create views, bind data to lists,
etc. This method also provides you with a Bundle containing the
activity's previously frozen state, if there was one. Always followed
by onStart().
onRestart() :
Called after your activity has been stopped, prior to it being started
again. Always followed by onStart()
onStart() :
Called when the activity is becoming visible to the user. Followed by
onResume() if the activity comes to the foreground, or onStop() if it
becomes hidden.
onResume() :
Called when the activity will start interacting with the user. At this
point your activity is at the top of the activity stack, with user
input going to it. Always followed by onPause().
onPause ():
Called as part of the activity lifecycle when an activity is going
into the background,
but has not (yet) been killed. The counterpart to onResume().
When activity B is launched in front of activity A, this callback will be invoked on A.
B will not be created until A's onPause() returns, so be sure to not
do anything lengthy here.
onStop():
Called when you are no longer visible to the user. You will next
receive either onRestart(), onDestroy(), or nothing, depending on
later user activity.
Note that this method may never be called, in low memory situations
where the system does not have enough memory to keep your activity's
process running after its onPause() method is called.
onDestroy() :
The final call you receive before your activity is destroyed. This
can happen either because the activity is finishing (someone called
finish() on it, or because the system is temporarily destroying this
instance of the activity to save space. You can distinguish between
these two scenarios with the isFinishing() method.