I would like to understand the following:
If we do a design of an activity that the UI is composed by multiple "child" fragments of that activity, if 1 of those fragments does something "costly" in the UI thread in the onCreateView does this affect all of the fragments?
Because if I understand correctly onCreateView is called only once
Yes it will affect all the Fragments if the Actvity they are attached to is affected.
According to Android Developer Guide on Fragment, once the Fragment is attached to the Activity, it's Life Cycle is controlled by the Activity e.g. if Activity is Destroyed the Fragment is too.
Fragment is just a like a little Activity so if there is possibility that fragment operation is likely to be long then AsyncTask or any other suitable service should be used. See below link for more details on Background Services;
https://developer.android.com/training/run-background-service/create-service.html
yes
it is effect all of the app
Related
According to Android Developer site, the correct way of communicating an activity with their fragment is through listeners.
https://developer.android.com/training/basics/fragments/communicating
My question is, this fragment is holding a reference to the activity... when the activity is destroyed, will the fragment manager release the fragment and thus the fragment will be collected and so the activity? or do they hold a strong reference that needs to be nullified too in the Fragment's onDestroy?
The Fragments Lifecycle is bound to the one of the Activity. Imagine an Activity as the Universe and Fragments as Planets / Stars. If the Universe dies, so do the Stars / Planets inside of it. Similarly, if an Activity gets destroyed so do all of it's Fragments.
The official documentation (which you should definitely check out) explains it very well:
A fragment must always be hosted in an activity and the fragment's
lifecycle is directly affected by the host activity's lifecycle. For
example, when the activity is paused, so are all fragments in it, and
when the activity is destroyed, so are all fragments. However, while
an activity is running (it is in the resumed lifecycle state), you can
manipulate each fragment independently, such as add or remove them.
When the activity containing the fragment is destroyed, so is the fragment automatically. Check this out
I just took a look at the two following examples of the fragment as a task holder approach:
https://android.googlesource.com/platform/development/+/master/samples/ApiDemos/src/com/example/android/apis/app/FragmentRetainInstance.java
http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html
Why did they need UiFragment in the first example? Messages from the task holder fragment can be sent to its activity directly as it's done in the second example.
Why did they need UiFragment in the first example?
They did not need that Fragment.
It's just a simple example, seems like they chose to use a Fragment for the content instead of calling setContentView() on the Activity.
There are two Fragments basically in the Google example:
A Fragment for the UI
A worker Fragment to retain the state of a Thread through the re-creation of the Activity (in case of an orientation change for example).
They could have just ditch the UI Fragment and call setContentView() on the Activity and it wouldn't make a difference. The point of the example is the worker Fragment.
Fragment transaction has method add(Fragment fragment, String tag), which does not place fragment to container, so it cannot have view. For what it can be used?
From the Android Documentation:
However, a fragment is not required to be a part of the activity layout; you may also use a fragment without its own UI as an invisible worker for the activity.
How about this purpose ?
Simple example: an Activity starts an AsyncTask, but when device rotated activity restarts, causing AsyncTask to lose connection with the UI Thread. But this Activity can hold a Fragment (invisible, with no UI at all) that can handle all the AsyncTask work. When Activity recreated the Android OS takes care reattaching the Fragment, thus no data loss will occur.
For Dialogs you don't have any container on normal app layer. It is directly added on Window with WindowManager(See WindowManager.LayoutParams for various types of layers).
DialogFragment has an API like DialogFragment.html#show(android.app.FragmentManager, java.lang.String) which corresponds to this.
You can use fragments without UI (container) as a background worker (one benefit is that you can retain it during rotations etc) and for retaining data during rotations and other changes.
Reading http://developer.android.com/guide/components/fragments.html is strongly recommended.
Example of instance retaining: https://android.googlesource.com/platform/development/+/master/samples/ApiDemos/src/com/example/android/apis/app/FragmentRetainInstance.java
Also, here are similar questions (so this questions seems to be a duplicated but cannot be flagged due to bounty):
What is the use case for a Fragment with no UI?
Android non-UI Fragment usage
As #Lucius Hipan mentions, it can be used to prevent data loss.
Almost always this king of fragments are used as Retained container ( setRetainInstance(true) called in onCreate method), then after device configuration changes (e.g. orientation changing) fragment will not be recreated but remembers previous state.
It's recommended way to use asynctask.
Here is an example:
There is login activity. The user enters their credentials and presses the Login button. After that configuration change occurs (user rotates phone). So, network task was completed, but your handlers was not listening for it now. If you show any login animation, it can be stored via savedInstance, but listeners not. And instead of creating service you can simply create new retained fragment with persistant asynctask and interface to communicate with activity.
This method is a good compromise for small projects where using bus libraries is overstatement.
By calling the method add(Fragment fragment, String tag) internally calls add(int containerId, Fragment fragment, String tag) with a 0 containerId.That will be add(0, fragment, tag).
If 0 is supplied as containerId, it will not be placed the fragment in a container.
I am new to Android Fragment and trying to learn Fragment to Activity communications.
What is the better approach(best practice) in Android for Fragment to Activity communication?
Lets say I have FragmentA and ActivityA.
After my screen popups FragmentA, I would like to perform somemethod(probably UI related) in ActivityA
Here are two(pattern) possible
Solutions:
In FragmentA getActivity and cast the Activity to ActivityA and then call somemethod.
In FragmentA create an interface callback and then implement that callback in ActivityA. Then on the callback, call somemethod.
Which pattern is more common/perfer in Android development and why. Or do you have an even better way to communicate from fragment to activity in Android to share with me?
Any comments, opinions, and suggestions is highly appreciated and welcome. ^^ .
The second solution is the preferred one, because it allows your fragment to be more independent of its hosting activity.
If in the future you decide to put your fragment on a different activity, there are no changes needed on the fragment, and you will only need to implement the interface on your activity.
I'll add a third solution which is using an event bus (Otto for instance), which also works, although some might argue that it makes your code a little less readable.
First method will be a bad practice. Second method will work fine but your fragment is going to be tightly coupled with your activity.
There is one more better approach is to use some event bus library like otto
Using this you can communicate effectively with loose coupling in your activity & fragment.
Your second approach is more flexible. You might not see a huge benefit in one activity and one fragment case. If you have to use the same fragment in another activity, it will most likely break by casting your activity like that. That said, there is nothing wrong with the first approach, but it is just a little restricted.
First pattern is best when your fragment is used only by one activity.
Second approach is needed if you want your fragment to communicate with some other objects not the activity that hosts fragment. If you always want to communicate with hosting activity callback is not needed. Just create an interface and implement it on as many activities as needed. Then in your fragment cast activity returned by getActivity().
MyInterface myInteface = (MyInterface) getActivity();
myinterface.somemethod();
You can even check if activity implements needed interface(s) etc.
The interface approach works fine and is more flexible in so far as it doesn't tie your fragment to the activity directly. One thing you should also consider is how much work the activity might need to do, that is it may end up managing several fragments. This has a tendency to lead to 'fat fragments' as my question here asked when I started using them
In Android docs, I found a specs on Activity lifecycle and on Fragment lifecycle individually, but never together. It does not seem obvious as I attached a debugger to FragmentActivity which hosts my fragment, and the life cycle is more than crazy. It looks like activity finishes first and then fragments starts, which is impossible.
Fragment's lifecycle
Activity's lifecycle
Logically, fragment should "jump into" activity's lifecycle after its onResume and it would end before activity's onPause, but it seems it is not happening.
Can someone either show me the lifecycle of the fragment in connection to its parent's activity or direct me to some good tutorial on this?
Have you seen this? Fragment is created after Activity is created. It doesn't seem possible for "activity finishes first and then fragments starts" Can you post the code for that?
This is what I tested, 1 FragmentActivity , two Fragments :