On Apr 12, 2012, at 8:02 PM, King Coffee wrote:
> I'm using the following code to allocate an image file to a ImageView
> control, with instance name: image.
>
> Bitmap bitmap = BitmapFactory.DecodeFile(matches[0]);
> image.SetImageBitmap(bitmap);
I've tried to expound upon this [0, 1], and I'm probably still not being clear
enough, so let's flip the question around...
When _shouldn't_ you call Dispose()?
You shouldn't call dispose when the runtime type is a C# type, the instance has
a peer held in Java code, and Java peer will be re-entering managed code.
Every Java.Lang.Object subclass has a corresponding (generated) Java peer type
[1]. When you create an instance of the Java.Lang.Object subclass, you also
create an instance of the Java peer type, and the Java peer and managed
instance are associated with each other. Calling Dispose() breaks the
association.
The problem with breaking the association is that once broken, if the Java peer
re-enters managed code, a new Managed Callable Wrapper (MCW) will be
instantiated, and a new mapping between the Java peer and the new MCW will be
created. If you had any instance state, it will be "lost", which can be quite
confusing. (Or you'll get an exception because the MCW type doesn't provide an
(IntPtr, JniHandleOwnership) constructor...)
Note that this only really applies to C# types. If you're only dealing with
Java types, you can dispose of the managed wrapper with (near) impunity; a new
wrapper will be create if (when) the Java instance is (re-)exposed to managed
code.
That is the fact with Bitmap: BitmapFactory.DecodeFile() will _never_ return C#
type that contains C# instance state. Consequently, there's no need to ever
preserve the association (unless you're storing `image` as a class member), so
you can kill the mapping as soon as you're done with it:
using (Bitmap bitmap = BitmapFactory.DecodeFile(matches[0]))
image.SetImageBitmap(bitmap);
The result of the above is that only Java code will refer to the Bitmap
instance, so when your code later changes the image's bitmap, Android will be
able to quickly release the Bitmap instance.
> I tried to dispose of the control's context as follows:
> image.Context.dipose(), image.CacheDir.dispose().
That won't hurt, but it won't really help either. As mentioned above, if there
isn't a wrapper for a Java instance, one will be created when the Java instance
enters managed code, so the next time you call `image.Context` you'll simply
get a new wrapper. (If you have an e.g. Dictionary<Context, object> you'll
likely invalidate your keys if you do that, too. Care must be taken.)
> But, do I real need to dispose of container control, image? and reassign it?
I don't think you'll need to dispose of the container control, I imagine that
just disposing of the image will be sufficient.
- Jon
[0]
http://docs.xamarin.com/android/advanced_topics/garbage_collection#Helping_the_GC
[1]
http://docs.xamarin.com/android/advanced_topics/architecture#Managed_Callable_Wrappers
_______________________________________________
Monodroid mailing list
[email protected]
UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid