OnCreateView doesn't get called after startActivityForResult() finish()es - android

I have a fragment that does a startActivityForResult() call in OnCreateView if there is no internet. In the NoInternet Activity there is a retry button that finish()es the activity (So I can supposedly check for connection again). When the activity finishes, OnCreateView of the fragment is never called (because OnCreate() of the host Activity is never called) and I end up not cheking if there is internet again.
Now a simple way around this is to check if there is internet in the OnStart() of the main activity (that hosts the fragment).
But I was wondering: Is there a way to force OnCreateView after finish()ing an Activity that was started with startActivityForResult()?

I think your problem is the understanding of the lifecycle of Fragments. If you call startActivityForResult() on a Fragment, it will be executed on the fragment's containing Activity. Now the Activity goes in the Paused and then Stopped state and also will the Fragment. If you finish the "ResultActivity" the states Started and Resumed will be passed through on the Activity and the Fragment.
So, how you said already, just move your connection checking and your startActivityForResult() call into onStart().
There is no need to create a new view for Fragment. If you want to alter the View programmetically you can do that in onStart() and onResume().
But don't break the lifecycle just for a method call which could be easiely invoked in another callback.

I'm not sure exactly how you're using the fragments/activities in question but it sounds like the fragment view of the main activity is not being destroyed when you call startActivityForResult() for the new activity. This behavior is normal under some cases which means which your fragment would only be stopped or paused. So, doing your network check in the OnStart() or OnResume() would be the correct usage.

Related

What will be the recommended approach to initialize view (UI) elements in android, OnCreate() or OnStart() method?

I have seen one of the tutorial on Firebase android in which they have initialized the view (UI) elements in OnStart() method of activity instead of OnCreate() method.
I know that the 'OnCreate()' method gets called once and 'OnStart()' methods gets called multiple times when we switch between the activities. I did some study but still wanted to know the exact reason why Firebase tutorial did that way.
I want to know what will be the recommended approach to do so and why?
Thanks in advance!!
onCreate is 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().
onStart is 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.
For Example Let us assume A and B activity, A activity has been created and currently in onStart() method is being called. When one switches to B activity then A's OnStop() method will be called and B activity will be created. Thus OnStart() OnStop() methods are called when you switches onto activities.
So according to your question initialization is done once so it should be done in OnCreate() method if it is done in OnStart() then initialization will takes place every time when you switch between activities.

onSaveInstanceState is not getting called

I have an activity which starts various activities for result codes and on getting results in onActivityResult method it starts appropriate activity based on result code.
onSaveInstanceState is not getting called in Activity which started for result.
For example Navigation Activity starts Activity A as :
Intent intent = new Intent(this, A.class);
startActivityForResult(intent, Constants.REQUEST_CODE);
Then A finishes by setting result code so App will redirect to Navigation activity again and onActivityResult method will called.
So my question is: Why Activity A's onSaveInstanceState is not getting called at finish and navigation back to Navigation Activity ?
onSaveInstanceState() is only called if the Activity is being killed.
I don't know what exactly you want to do in that method, but you probably should move your code to the corresponding methods of the Activity Lifecycle.
from http://developer.android.com/reference/android/app/Activity.html :
Note that it is important to save persistent data in onPause() instead of onSaveInstanceState(Bundle) because the latter is not part of the lifecycle callbacks, so will not be called in every situation as described in its documentation.
Also the method description for onSaveInstanceState() describes exactly your situation:
Do not confuse this method with activity lifecycle callbacks such as onPause(), which is always called when an activity is being placed in the background or on its way to destruction, or onStop() which is called before destruction. One example of when onPause() and onStop() is called and not this method is when a user navigates back from activity B to activity A: there is no need to call onSaveInstanceState(Bundle) on B because that particular instance will never be restored, so the system avoids calling it. An example when onPause() is called and not onSaveInstanceState(Bundle) is when activity B is launched in front of activity A: the system may avoid calling onSaveInstanceState(Bundle) on activity A if it isn't killed during the lifetime of B since the state of the user interface of A will stay intact.
The method onSaveInstanceState() isn't called when an Activity finishes naturally like on a back button press. That's your app itself destroying the Activity. The method is only called if the Android OS anticipates that it may have to kill your activity to reclaim resources.
If the Activity then actually gets killed by Android, the OS will make sure you receive a call to onRestoreInstanceState() as well passing the same bundle you used to save your activity's state in onSaveInstanceState() method.
From the docs:
This method is called before an activity may be killed so that
when it comes back some time in the future it can restore its state.
For example, if activity B is launched in front of activity A, and at
some point activity A is killed to reclaim resources, activity A will
have a chance to save the current state of its user interface via this
method so that when the user returns to activity A, the state of the
user interface can be restored via onCreate(Bundle) or
onRestoreInstanceState(Bundle).
I had the same issue happening to me on a "drawer menu" part of a "main activity", because I had overridden the "onSaveInstanceState" method in my main activity but had forgotten the call to super.onSaveInstanceState() (which, as a result, would never call the "onSaveInstanceState()" method of my "drawer menu" which was part of this main activity).
In other words: make sure you don't forget your calls to "super.onSaveInstanceState()" where necessary.

OnDestroy() called multiple times

I have noticed that the onDestroy() method of a fragment gets called multiple times - why would this be? I would expect only 1 call.
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.
It's normal for an Activity or Fragment to get onDestroy()-ed multiple times. For example, when you change the device orientation, the current Activity goes through onDestroy() and then a new instance of the same Activity goes through onCreate(), now in the new orientation.
You might be confusing this for finish(), which gets called when the Activity gets "killed" per se and happens only once when you navigate away from it.

abnormal behavior of parent activity after finishing child activity

I have Activity A and I am calling Activity B from Activity A using setResultForActivity.
Now in Activity B when I press Done button I am firing finish() and it returns to
Activity A and it return down to onActivityResult. Now the issue is after when I fired finish() in Activity B , Activity A's onCreate doesn't get called and thats why
some of the custom listeners in my ListView isn't working , it seems that they are not bind.
so the whole activity respond pretty weirdly , can anyone has solution to this ?
Why a fourth answer? Because in my view, the others aren't fully correct.
Truth is, Activity A could have been destroyed in the meantime, or not. This depends on whether Android needs memory or not. So it is possible that Activity A´s onCreate() is called (along with the other lifecycle callbacks), or not. In the latter case, onActivityResult() is called before onResume().
While for configuration changes, the most efficient way to preserve the Activity's state is via nonConfigurationState, if you want to prepare for a restart of your Activity after it has been destroyed, you can use the InstanceState mechanism, because while Android destroys your Activity A, it will keep its intent and saved instance state to re-crearte it.
This stresses the absolute necessity to place initialization exactly in the callback where it belongs.
To test whether your Activity logic works regardless of whether Android destroyed it or not, you can use the DevTools setting "Development Settings" -> "Immediately destroy activities". The DevTools app is available on AVDs and can also be downloaded from Google Play.
Just place your onCreate() stuff in onResume() of Activity A except setContentView().
Just have a read on Android Activity Lifecycle : http://developer.android.com/training/basics/activity-lifecycle/stopping.html. onCreate() is only called when the activity is first created. You can do your list thing in the onResume() method.
Activity A's onCreate won't get called because the activity has not been destroyed. When an Activity regains focus from another activity, it's onStart and onResume get called, so I would put your bound listeners in those. They will also be called when onCreate is normally called.
After your child activity is finished() it return to execute onActivityResult which is in your case in Activity A. The onCreate method is not supposed and does not get called when killing of you sub-activity, a.k.a Activity B.
Please post some source code for us to work on and I will improve my answer! :)

Again on Activity lifecycle: onStart is called when it shouldn't be

First of all, I've read the great explanation of how the activities start, suspend, resume and stop. It's fine but I have another problem.
The Activity lifecycle diagram in the Android reference tells that if I call another activity, onPause() will be called for the calling activity, and later, when the other activity is over--the caller will resume via onResume().
So if the first activity is Main and the other one is Other, the cycle would look like this (pseudocode):
Main.onCreate()
Main.onStart()
Main.onResume()
// Main is running... Then, the user clicks a button and Other comes in front.
Main.onPause()
Other.onCreate()
// Other's lifecycle goes here... Finally, the user returns back.
Main.onResume()
// Main is running again.
This is what the diagram tells. But my Main gets onStart() first, then onResume().
Why is that? Do I misunderstand something?
That is happening because your Main activity is totally disappearing from view, which triggers onStop, which triggers OnStart when you resume. If you only partially hid the view from your Main, you would only get onResume.
If you look at the diagram, between onPause and onStop, there is this "the activity is no longer visible"... that's what you are encountering.
For quick reference, the activity lifecycle graphic:
One reason of your onStart() is getting called in for main application is that your Main activity is stopping. That is its onStop() is being called. In this scenario firstly onStart() and then onResume() will be called.

Categories

Resources