In creation of a fragment, I encountered getActivity() to be null.
So to narrow down the problem, I kept a local copy of activity in onAttach(Activity activity), which by definition is when it is attached to an activity.
However, I logged the activity in onAttach, and it is still null.
I'm only running into this problem in 2.3.6 and below.
Is this a known problem with support package?
The series of methods called to bring a fragment up to resumed state are:
onAttach(Activity) called once the fragment is associated with its activity.
onCreate(Bundle) called to do initial creation of the fragment.
onCreateView(LayoutInflater, ViewGroup, Bundle) creates and returns the view hierarchy associated with the fragment.
onActivityCreated(Bundle) tells the fragment that its activity has completed its own Activity.onCreate().
onViewStateRestored(Bundle) tells the fragment that all of the saved state of its view hierarchy has been restored.
onStart() makes the fragment visible to the user (based on its containing activity being started).
onResume() makes the fragment interacting with the user (based on its containing activity being resumed).
The bold method should be the one where getActivity doesn't return null anymore.
the onAttach method should not be used to call methods of the activity object, It should be used to initialise callback interfaces. An example of these interfaces can be found here.
This problem is because of the support package it means the fragment are from android 3.0 and up that is API level 11 and UP so for sure you will face app crash for android 2.3.6 gingerbird
this.getActivity();
Related
onActivityCreated seems to mean "This fragment callback is executed just after the activity has been... created... I mean, just after the fragment is correctly attached to the activity. There, you can safely call getActivity, it won't return null, except if the activity is null for some special reason".
However, I've seen that the fragment callback onAttach is called even after OnCreate, it means that the fragment has been attached to the activity, which has been created.
The complete workflow for a fragment (and for a fragment dialog, which is frequently left behind) is: onAttach -> onCreate -> onCreateView -> onActivityCreated. So in each of these 4 methods (perhaps not onAttach I don't know), the activity is normally not null and attached to the fragment.
So my question is: why does the callback onActivityCreated since the activity is, in fact, already created and attached to the fragment 3 callbacks ago???
So basically in onAttach() we get confirmation is that activity is attached to my fragment, I can use getActivity() to fetch things like resources like
getActivity().getResources.getDrawable(R.drawable.abc)
but Suppose if You want to fetch the views inflated in activity's xml like If you want to access
getActivity().findViewById(R.id.Myelement)
You might get null here, so OnActivtyCreated() ensures that activity's view is inflated, You can access activity's views now (Activity's view has been created (onActivityCreated))
This question already has answers here:
Android: Where to put activity's onCreate() code in a fragment?
(2 answers)
Closed 8 years ago.
I have started working on fragments.Before starting i wanna clear a doubt whether when to use
onActivitycreate() and onCreate().I did many research but cound not find any relevent answer.Please help.
onActivitycreate() :
onActivitycreate() Called when the fragment's activity has been created and this fragment's view hierarchy instantiated. It can be used to do final initialization once these pieces are in place, such as retrieving views or restoring state. It is also useful for fragments that use setRetainInstance(boolean) to retain their instance, as this callback tells the fragment when it is fully associated with the new activity instance. This is called after onCreateView(LayoutInflater, ViewGroup, Bundle) and before onViewStateRestored(Bundle).
onCreate():
The system calls this when creating the fragment. Within your implementation, you should initialize essential components of the fragment that you want to retain when the fragment is paused or stopped, then resumed.
Read this doc for more details: Fragment Activity Life cycle
onCreate() is sort of like a constructor for the Fragment class, where you normally initialize some variables. In many cases onCreate() is not overriden at all, although it is important to manually define a public empty constructor for every Fragment class.
onCreateView() is the most important method to override when you a create a Fragment (at any rate a Fragment that has a UI). It is analogous to the onCreate() of an Activity: here you inflate the View of the Fragment.
onActivityCreated() is called after the Activity to which the Fragment is attached has been created (i.e. the Activity's onCreate() method has returned without errors) and after the Fragment's View has been inflated.
I'm currently having issues with fragment lifecycle management.
Should the activity the fragment is hosted in be recreated I have set SetRetainInstanceState(true) to keep the fragment instance alive.
However, this had lead to some strange behaviour regarding my views. Sometimes I get memory leak warnings concerning a few fragment views and nullpointer exceptions to the activity context.
Wanting to make sure the fragment instance is retained properly: what are best practices regarding the retaining of a fragment (what to keep, what to destroy)?
SetRetainInstanceState(true) makes sure Android retains the fragment while the activity is being recreated. Therefore the activity the fragment was first attached to is not longer there after activity recreation and the fragment is attached to a new activity instance.
To make sure this goes well keep the following things in mind:
Do not keep a reference to the attached activity in your fragment unless absolutely necessary. Use the getActivity() method instead which will always return the currently attached fragment (or null if nothing is attached).
If you absolutely have to have a "permanent reference" to the currently attached activity (in which you might want to rethink your design) make sure to update this reference in the onAttach and onDetach methods.
Make sure you retain no object that was initialized using the activity as a context (usually views, adapters and such). To do this, override the Fragments onDestroyView() method that gets called just before activity recreation. Here you can dispose of the views and adapters the fragment still has a active reference to (usually just setting their reference to null should be enough). You can then recreate the fragment's views and adapters using the new context in the onCreateView call.
My application contains two fragments.
My Android manifest file contains the following line:
"android:configChanges="orientation|screenSize"
which I need for the second fragment. I don't want its onCreateView() or other method to be called an orientation change.
But my first fragment needs onCreateView() to be called when orientation changes. Since the manifest file contains the above line, the onCreateView() method is not called. Can anyone help me in sorting out this to make onCreateView() to be called when orientation changes for specific fragment?
I believe setRetainInstance() is the function you need.
From documentation:
Control whether a fragment instance is retained across Activity
re-creation (such as from a configuration change). This can only be
used with fragments not in the back stack. If set, the fragment
lifecycle will be slightly different when an activity is recreated:
onDestroy() will not be called (but onDetach() still will be, because
the fragment is being detached from its current activity).
onCreate(Bundle) will not be called since the fragment is not being
re-created.
onAttach(Activity) and onActivityCreated(Bundle) will
still be called.
I'm trying to change the activity title from a fragment (in this case, it's an android.support.v4.app.Fragment). To this end, I save the activity in an attribute on the fragment when onAttach() is called on the fragment. According to the docs, onAttach() should be called before onCreateView(), which I'm using to request some data used to fill up the view. When I kick off the thread for the network retrieval, I want to indicate that in the title, so I'm trying to call this.activity.setTitle() from the Fragment. However, that keeps throwing a NullPointerException. What am I missing here?
You can access the Activity in a Fragment using getActivity(). It can be called safely as soon as onActivityCreated() was called on the Fragment. Before that, it might not be there or might not have been fully initialized yet.
If your thread starts before that, just note the fact somewhere in your Fragment and only change the title after onActivityCreated was called.
Nowadays you can call requiredActivity() too that return FragmentActivityobject and if fragment doesn't come from an Activity, method throws a IllegalStateException