Hi,

Thanks for the replies, but I think I may have presented the problem
incorrectly.

I have a problem of knowing when a *view *will be disposed of. I have
created a Control that derives from View. This control has a temporary
cache of low res images that it uses. I then use this Control in various
places.

In order to dispose of this cache, I can do something this:

override *MyActivity*.OnFinish()
{
    this.*myControl*.DisposeImages();
}

But this is  not what I really want to do. I don't want my activities to
have to know about when and what my view's images and data are doing. What
I would like is:

override *MyControl*.ViewIsDisposing()
{
    this.DisposeImages();
}

I don't know if something like this exists. But currently I am doing
something like this:

override MyControl.OnDetachedFromWindow()
 {
     this.DisposeImages();
}
override MyControl.OnAttachedToWindow()
 {
     this.CacheImages();
}

This probably will result in the images being cleared and re-cached if the
control is moved around, but this is not such a big problem. Is this method
ok to use. I currently know that when I add the view to the layout, my
images are cached. When I close the activity, my view is unloaded, thus
resulting in the control being detached. This results in my images being
clear. Which is good so far.

Are there any comments or different ways of doing this?


Matthew


On Mon, Jun 18, 2012 at 10:58 PM, Jonathan Pryor <j...@xamarin.com> wrote:

> On Jun 18, 2012, at 10:16 AM, Matthew Leibowitz wrote:
> > As my last question suggested, I am working with images. I cache the lo
> res in an array member of a view, but how do I dispose of the images?
>
> By Dispose()ing of them. :-)
>
> > I tried overriding the Dispose(bool) method, but that doesn't seem to be
> called when the Activity is closed.
>
> Dispose(bool) is called by the GC when the value can be collected. This
> will be some point after the Activity is closed, but not immediately after,
> unless you null out your Bitmap fields and call GC.Collect() in
> Activity.OnDestroy(). (Even GC.Collect() may not work immediately, and
> would still require that you null out all Java.Lang.Object-subclass
> fields...)
>
> > What am I doing wrong? :) Is there another method/place?
>
> > The "dispose" should be called when the containing activity is closed,
> but I don't want either the Activity or the View to know about each other.
> > This is because they are used in a few places, but in slightly different
> ways.
>
> I'm not entirely sure how your View is obtaining the array from your
> Activity...but it might not matter.
>
> Let's assume you have code such as [0]:
>
>        Bitmap[] bitmaps = new Bitmap[100];
>        for (int i = 0; i < 100; i++) {
>                bitmaps[i] = BitmapFactory.DecodeFile(...);
>        }
>
> Every Bitmap instance will contain a gref, and gref acts as a GC "root",
> preventing the Java VM from collecting the Java-side object [1]. The above
> will thus necessitate that 100 gref's exist until all 100 Bitmaps instances
> are Dispose()d, OR the GC is able to collect all of them:
>
>        for (int i = 0; i < bitmaps.Length; i++)
>                bitmaps [i].Dispose ();
>
> Can you do better? Somewhat:
>
>        JavaList<Bitmap> bitmaps = new JavaList<Bitmap>();
>        for (int i = 0; i < 100; i++) {
>                using (var bitmap = BitmapFactory.DecodeFile (...))
>                        bitmaps.Add (bitmap);
>        }
>
> The `using` ensures that the managed Bitmap peer instance is disposed of
> ASAP. The above code will require only 1 gref: the gref for the
> JavaList<Bitmap> instance.
>
> When you access `bitmaps`, a new managed peer will be created, which will
> acquire a new gref:
>
>        Bitmap b = bitmaps [0];
>
> To ensure that the gref is disposed of as quickly as possible, you'd still
> want to Dispose() of it:
>
>        using (var b = bitmaps [0])
>                DoSomethingWithTheBitmap (b);
>
> However, since JavaList<Bitmap> still has a gref, everything it references
> will also be kept alive. You'll have 1 gref, but you still have 100 Bitmap
> instance hanging around at once. To allow Dalvik to collect them, you need
> to release the gref:
>
>        bitmaps.Dispose ();
>
> The `bitmaps.Dispose()` call could thus go in Activity.OnDestroy()
>
>  - Jon
>
> [0]
> http://stackoverflow.com/questions/11081806/larger-memory-footprint-when-using-bitmapfactory-decodefile-in-c-sharp-and-huge
>
> [1] http://docs.xamarin.com/android/advanced_topics/garbage_collection
>
> _______________________________________________
> Monodroid mailing list
> Monodroid@lists.ximian.com
>
> UNSUBSCRIBE INFORMATION:
> http://lists.ximian.com/mailman/listinfo/monodroid
>
_______________________________________________
Monodroid mailing list
Monodroid@lists.ximian.com

UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid

Reply via email to