Sunday, July 29, 2012

Re: [android-developers] Fragments Bitmap Recycling + a bunch of bitmap oriented questions.

Worried about memory?  Try this:

<application android:largeHeap="true">


On Sunday, July 29, 2012 4:11:55 AM UTC-5, Dmitriy F wrote:
I've written a simple test where I have:
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.hide(_sv);
ft.commit();
When the fragment gets hidden - onPause doesn't get fired. However, system fires a chain of callbacks up to onDestroyView when I use a replace method. So, I guess, I should be performing memory-recycling operations in onDestroyView method.

I've also noticed that when I hide the ViewPager component with setVisibility(GONE) its' fragments dont fire onPause callback. Is there any workaround to tell all the  fragments inside the ViewPager to clean themselves with onDestroyView ?

I still think I should use fragments since in a Tablet version those pages are implemented as tabs.

Thanks again and I was wondering whether you could point out or give some links on implementing the memory management process. I have a lousy knoweledge about WeakReferences, recycle(), System.gc() features but I guess they are somewhat mutually-excluding. Probably, I should stick to Weak/Soft references approach, should I ? If so - could you share some insights/give link on the whole process of instantiating bitmap down to the recycling.

On Sunday, July 29, 2012 12:28:08 AM UTC+3, Dianne Hackborn wrote:
If you have a fragment that holds on to a lot of memory in its view hierarchy and are concerned about this, then use FragmentTransaction.remove() to make it no longer visible -- that will remove it from its parent view and destroy its view hierarchy, so it doesn't hold on to any references.  (If you are manually loading bitmaps in the fragment, in onDestroyView() you can clear the references there.)  Of course this means a bit more overhead when the user returns to the fragment, since its view hierarchy needs to be re-inflated and initialized again.  But it won't be any worse than the first time the user visited it, and you need that to be fast as well.

It is true that FragmentTransaction.hide() does not remove and the destroy the fragment's view hierarchy, just doing View.setVisibility().  But that is not all -- it takes care of managing the fragment lifecycle so that fragment will be paused and stopped (since it is no longer visible).  You can implement the lifecycle to free up resources if you need to.  This will also result in them being freed when the entire activity is stopped, which is probably what you want as well.

You shouldn't be directly hiding the view associated with a fragment.  That is what FragmentTransaction.hide/show() is for.  There is no need to directly hide the view owned by it, and doing so means that you are letting the correct fragment semantics execute.  (And for what it's worth, if you have no reason to use fragments with ViewPager, there is nothing forcing you to -- you can write your own adapter that directly manages raw views and doesn't use fragments at all.)

On Sat, Jul 28, 2012 at 1:45 PM, Dmitriy F <midnight.88s@gmail.com> wrote:
Thanks for the answers! Would you mind to suggest on the part about fragments, bitmaps and memory management ? I decided to implement the app with 3 activities and about 8 fragments. The fragment number might slightly increase yet I think it's not the fragments but their bitmaps that gonna cause troubles with memory. 

For displaying the fragments I have two containers: a ViewPager(rotates 3-4 fragments) element and a FrameLayout(displays strictly one fragment) element. Right now I'm simply hiding one type of container and showing another - setVisibility or fragmentTransaction.hide (I haven't figured out what is the difference between these two apart from the latest gives an ability of adding to activity's backstack). Is their any better way of switching between the containers ?

Additionally, even if those fragments might not hold much memory by themselves - should I wrap those objects with SoftReference ?

Could you tell any precautions/advices for implementing an app with such structure ? Thanks.


On Saturday, July 28, 2012 9:36:27 PM UTC+3, Romain Guy (Google) wrote:
1) Does ImageView.SetImageResource applied against the same id twice or thrice consumes memory for the same bitmap or uses a separate range for every imageview element ?

I don't quite understand your question. When a Bitmap is loaded as a Drawable (which is what ImageView does), it gets cached by the system (using weak references.) This means that if do this:

Drawable d1 = loadDrawable(R.drawable.myImage);
Drawable d2 = loadDrawable(R.drawable.myImage);
 
you will get 2 different instances of Drawable, but the underlying Bitmap will be loaded in memory only once.

2) same as 1. but for BitmapFactory.decodeResource

Every time you call this method you will load a new instance of a Bitmap object, which means you will use more memory.
 
3) What part of Bitmap object consumes the most memory. If it's "backbone memory object" than what is it ? Where can I elucidate the structure of bitmap memory for myself ?

A Bitmap is backed by a byte array containing all the pixels. This is what consumes the most memory. As of Android 3.0, this byte array can be found in Bitmap.java, in previous versions of the platform the pixel storage exists on the native side (you'd have to investigate SkBitmap.cpp.) 

--
Romain Guy
Android framework engineer
romainguy@android.com

--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en



--
Dianne Hackborn
Android framework engineer
hackbod@android.com

Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails.  All such questions should be posted on public forums, where I and others can see and answer them.

--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

No comments:

Post a Comment