For couple of days, I have a question in my mind that couldn't find any answer for. Right now I have an android app that I use 1 fragment and a view pager with 3 fragments. What I wonder is, is there any performance difference between those two? Will using of fragments provide me less cost than using activities? What would be good for RAM/CPU of device while changing layouts; skip from one activity to another or skip between fragments of viewpager? Because if I use activity, than everytime a window will pop up. But in viewpager's fragment I will stay in one activity and will change only pages. Will that provide me performance on device or is just an UI issue?
Thanks in advance.
A ViewPager works in this way: Let's say it has n pages, or Fragments. If you are on index i, Android will ensure Fragments i-1 and i+1 and their Views are instantiated. As you page from side to side, subject to memory and the "Don't keep activities" setting, you will keep instantiating Fragments until all Fragments are present in memory. When you side from side to side, Android uses OpenGL to smoothly slide one Fragment's View over onto the screen while sliding the other out.
Contrary to some other answers, Android does not instantiate all Fragments when the ViewPager starts - instantiation is lazy. In addition to the default behaviour described above, you can control memory use using the setOffscreenPageLimit().
This is the key difference from the older Activity stack model which instantiates Activities only when called.
There are several consequences:
When the ViewPager is first shown, the CPU will be more active since it has to instantiate the Fragment being shown and those off-screen to the left and right (2x or 3x the equivalent work)
Since all the Fragments stay in memory, memory use will be (slightly) higher. If your Fragments don't use much memory, the difference in memory usage is trivial.
If there is memory pressure (or "Do not keep Activities" is on), then only 2 or 3 Fragments are kept; other fragments are suspended so you need to ensure the onSaveInstanceState() is implemented correctly. When the user slides back, the Fragments will be resumed. However, resuming a Fragment is less CPU intensive than creating the equivalent new Activity
Once the Fragments are instantiated, as the user slides from side to side, CPU use will be lower and (most importantly) the UX will be much smoother since the Views are already present and rendered in memory.
Communication between Fragments is relatively easy using the parent Activity as the communication hub.
One other point: The ViewPager's UI metaphor is different to the Activity stack. When weighing which approach to take, you probably should value the UX more than the implementation details (CPU and memory) unless the implementation costs are extreme.
There is the difference b/w those 2:
If you use fragments then the first time your activity load, it will load ALL of your fragments as once (a huge memory consumption here if you have many fragments, but in your case, 3 fragment maybe acceptable). But as it load ALL as once, you can move back and forward without delaying (it's obvious for a view pager anyway). So if the requirement allow users to move back and forward your pages then Fragment is the choice, the problem is how you can manage the memory consumption to avoid memory leak or out of memory exception.
If you use activity (many activities) instead of fragments then the memory will stack up every time you move forward and unstack every time you back. It seems more efficient but the problem many occurs if each activity contains a large image which take a bit long to load. Therefore, every time you move back or forward there WILL be a delay which is not nice for user to observe. So, if the requirement only allow user to move forward, the using activity instead of fragment is obviously right.
In conclusion, depending on your application requirements and how you manage the memory issue to use Fragment or Activity. These are only my experiences and observations, I'm not guarantee that's true in any cases. There maybe a better explanation that I haven't know yet. Hope this help and English is not my native language, if you don't understand leave comment below.
Related
When using a fragment transaction we can do them using add and replace methods. If we use add, the previous fragment is not destroyed and kept in memory. And if we use replace the previous fragment is destroyed and recreated again when we go back. From an optimum (memory, cpu, etc) perspective what is more effective/better?
I've created a simple app that is capable of replace or add a fragment, you can find it here.
Following the android documentation I've used their tool to test the performace, those are the results:
By adding the fragment the usage of the cpu peaked was 17%
By replacing the fragment the usage of the cpu peaked was 23,3%
If you are talking about memory usage, then replace is better than add, because in add() the fragments's (which are in a stack of fragments) views are in memory, and all the images and views are taking memory, which is not released. Suppose you have 5 fragments A, B, C, D, E. You have added them one by one A->B->C->D->E Now E is at the top and all fragments A, B, C, D have their views and resources loaded in the memory, Suppose these fragments have a lot of heavy images, then there are chances your app may face out of memory. But If you use replace for each of them, their views are released so their resources are released (which is good, as these are no more visible to the screen, so should not hold resources, images and memory).
For more information, Google has introduced Jetpack navigation https://developer.android.com/guide/navigation
In this when fragments navigate from one to another, replace is performed.
The only thing required in case of replacing, is you need to handle onCreateView() properly so when the user comes back to destroyed fragment, Its views are populated again.
It depends on your scenario. Replace seems as better option generally because creating a new hierarchy doesn't cause a performance downfall and it releases its view hierarchy without destroying fragment instance if you save it to your back stack. However, there is some cases you should be aware of for example: you create a view like map view. It takes much time to create a view from scratch so you should keep that view in memory to prevent creating the view again and again user backs to this fragment. However if your memory starts to reach it bounds you should take care of it like destroying the fragment by using memory callbacks.
Most of the cases, replacing fragment is better option. You can see what happens when you add your fragment to a container without replacing previous one by not setting a background to your fragments.
As summary if your fragments take so much time to create its view hierarchy, you keep the view hierarch by transactions of show and hide not adding each fragment top of another. But if the fragment has a lightweight view hierarchy to create replace it.
I have one very general question, I did not find a concrete answer for my question hence putting it again.
I want to decide between two approaches
Dedicated activities for various various screens and tasks to avoid complexity and issues
Single Activities and multiple fragments for different tasks and user can navigate like Activity holding Fragment A user will navigate to Fragment B, Fragment C , this can be back and forth transaction.
What I want to know?
Is Activity transition is that costly for processor or to achieve simplicity memory overhead is negligible ?
Fragment has overhead of managing life cycle with transition, so what all problem can come with this life cycler management?
How easy is to deal with fragment transaction with saving state of the fragment?
We don't know right now what amount data will be there for fragment to hold.
Well, it totally depends on the application's design, flow and it's navigation.
Here are some benefits of using Single Activity and Multiple Fragments:
Performance fragment transactions are fast than creating new activities.
Navigation Drawer and Toolbar, it's easy to manage with Single activity.
Same Context can be used everywhere.
Fragment's setRetainInstance is very helpful while managing orientation changes.
with it, here comes few drawbacks:
Activity gets really messy with a lots of code.
Handling button backpress is tedious as only Activity can handle that not Fragments.
I personally use Multiple activities with multiple fragments in which I separate activities based on the modules. In same module, submodules can be created in fragments. I found it easy to manage in different scenarios as if application gets closed, reopens, in notifications, orientation changes.
My question is same, till now in my all app, there is only one Activity, and the rests are Fragments. I agree it is hard to maintain Fragment, but using Fragment will increase your Performance.
Suppose, take one example,
I have 10 Activities, in each Activity, I'm calling Async Task to perform some background operations. In each Async Task's onPostExecute() you are updating your UI. But before completing the doInBackground() you switched the Activity and that Activity is destroyed, but remember the doInBackground() is still in progress, and once it is finished, onPostExecute will be called, and in onPostExecute() we are updating the UI, but the Activity is destroyed, so this will create a leak in your app.
But if you are maintaining only one Activity then it will be easy to maintain.
Waiting for others opinion also.
Apart from answers above, few points which I would add which can help in deciding when to use a Fragment and when to use an Activity.
If you're supporting larger screen sizes, fragments are definitely preferred over activities.
When you've some code which you think can be reusable in multiple screens, you can use a fragment which can be reused across different places
A small point to add in support of "single Activity multiple fragments".
Sometimes you may need a component (a banner ad for example) to persist between different pages/screens of your app. If you have multiple Activities, you'll need to recreate that component on each of the Activities. But if you have a single Activity, you just add that component to the Activity layout and can forget about it.
As the title suggests, I want to retain my fragments. I have enforced my app orientation to always be in landscape mode in the manifest file so that there will be no rotations.
I have read:
Understanding Fragment's setRetainInstance(boolean)
and
Why use Fragment#setRetainInstance(boolean)?
However, I am not sure if they apply to my situation.
My project consists of a ViewPager with swipe tabs. How can I ensure that the fragments used in the ViewPager are the same ones as created when the MainActivity first starts? Would I use the same tagging method and findfragment by tag?
Additionally, where would it be best to check for the tagged fragment, else create a new fragment?
Just a side question related to ViewPager: what can I do to immediately create all fragments used in the ViewPager when the mainactivity is started, rather than to wait for a swipe event to occur?
To answer your last question view pager will by default create the fragments around the current fragment so you don't need to worry about that part. What I would recommend is let the view pager manage your fragments for you rather changing the behaviour since you might face performance issues.
SetRetainInstance simply keeps the instance of your fragment when its detached so it's up to you to assess whether you need to use it or not.. is there anything you want to maintain about that fragment? if not then do not use it, free your memory as much as possible.
For the last question, why do you want the same fragments created from the first time to be retained ? all the time? if you NEED to do that then rethink your structuring. gracefully recreate your fragments and maybe have some caching of your data on another layer if that is what you are worried about.
I am new to developing on android, finding myself somewhat confused regarding fragments and activities, and when to use the former specifically.
I want to achieve the following:
Have an activity with buttons for displaying different graphs. The selected graph should appear on screen in a panel overlaying the screen, or in fullscreen, and it should have functionality/buttons e.g. for selecting a graph timeframe.
Would creating each graph-page as fragments, routing events to the main activity be a good idea here, or should I just make a new activity for each? Or are there better options?
Cheers
I wouldn't recommend to use separate activities for this task.
The fragments are a great option for your case. You can save the state of each fragment and thus avoid recreating the graph views every time (which saves lots of CPU time if amount of data is big).
Read info about FragmentTransaciton and of course learn about working with Fragments in general. Maybe you should also try using ViewPager if you want to avoid switching fragments by yourself.
In case of using ViewPager you should use FragmentPagerAdapter (this one saves fragments for you) and you will just switch between them from your MainActivity. In each of the fragments you will implement your own graph with its own (or shared) layout file.
This version of the pager is best for use when there are a handful of typically more static fragments to be paged through, such as a set of tabs. The fragment of each page the user visits will be kept in memory, though its view hierarchy may be destroyed when not visible.
sorry for asking this question again. I have read all related articles, but haven't figured out what is better to use and when.
My app is going to be online store native client.
So I have a bunch of different screens in my app.
First Screen. It will be main screen like in the most online stores. There will be image slider, last new products, sales, ad and other common stuff for store.
Second screen. There will be simple list of categories in the store, without any ad,sliders and so on. Only list (RecyclerView).
Third screen. Will represent description of product, price, photos and other.
Fourth screen. Login and sign up screen to let user login in it's account.
There would be a lot of other screens required for native store client.
I have some questions about this.
I have watched the video, where lecturer said that in their app they are using only one activity for all app except settings and payment. So it makes app smoother, responsive because fragments are more lightweight that fragments. Okey, in this case we have base Activity, it should implement all callbacks from fragments to handle data and replace screen with another fragment.
We can use event bus to make it easier to with callbacks, but there is another problem.
How my activity layout should be built, it should have one fragment container and we can replace whole screen with another fragment or activity should include several fragments. For example for each image slider, ad, last products use its own fragment?
If we will use one container, so in this case we change whole screen. Is there any benefit of using fragment in this case ?
If use several fragment per screen. We have to put them in parent framgent ? In this case we are dealing with nested fragments. In most cases it is bad practice to do so.
Or we have just to know about all fragments currently present on the screen and when we have to change all screen view remove all old fragments and add new ?
What about nested fragments? Is bad to use them, and I have to do my best to get rid of them ?
Please explain how to build app to make it responsive but also to make code pattern and best practices oriented.
Thanks everyone for the help in advance.
I tried both ways, each for long period of time! I think both ways of developing applications are completely okey! I prefer fragments mostly because app looks and feels smoother but working with fragments may add a little bit of complexity to your application especially in your first project.
Should you have only one container in activity? Yes! because it doesn't matter how complex your app is, you always have some simple pages like about us, contact us, etc. and most likely they need to be full screen size! So your main activity should only have one container.
Is using nested fragment a bad idea? No! there is nothing wrong with nested fragments, in fact using nested fragments correctly will reduce the complexity of your app, that's because your main activity doesn't have to worry about little details in fragments, there transitions, navigation, etc.
Is using multiple fragment in one screen okey? again yes! that's the beauty of fragments, you arrange them as you like. Only ask one question before using multiple fragment in a screen. Do i need fragments or i just need to combine some views together?! In second case you don't need fragment, You can build a custom view that's combine some views together. (for example two textviews and one button for logging screen). Now instead of login fragment you have logginView than you can use like any other view.
Last thing you should know is using one activity increases the chance you get memory leaks (in particular activity leak) and when you get a memory leak it will be harder to find and handle it. why? because every fragment has a reference to activity (remember method getActivity?) so if you leak any fragment you also leak the activity and since your activity contains a lot of things you leak all of them all together!! And also all views have a reference to context. So again if you leak one view by accident, you leaked everything!! So be very careful about memory leaks. here is a detailed artical about memory leaks here http://goo.gl/7YDCK7