[mono-android] Problem with WindowManager

Narcís Calvet narcis at steema.com
Wed Mar 16 04:40:48 EDT 2011


Hi Jon,

Thanks for the info. That fixed the issue.


Best Regards,
 
Narcís Calvet
Steema Software
http://www.steema.com 
http://twitter.com/SteemaSoftware 
https://www.facebook.com/SteemaSoftware

-----Original Message-----
From: monodroid-bounces at lists.ximian.com
[mailto:monodroid-bounces at lists.ximian.com] On Behalf Of Jonathan Pryor
Sent: dimarts, 15 / març / 2011 18:04
To: monodroid at lists.ximian.com
Subject: Re: [mono-android] Problem with WindowManager

On Mar 15, 2011, at 11:23 AM, Narcís Calvet wrote:
> I’m trying to get the display size using the code below in an Activity.
>  
>       Java.Lang.Object windowService =
this.GetSystemService(Android.Content.Context.WindowService);
>       Android.Views.IWindowManager windowManager = windowService as
Android.Views.IWindowManager;
>       Android.Views.Display display = windowManager.DefaultDisplay;
>       String str = display.Width.ToString() + " x " +
display.Height.ToString();
>  
> I’d bet this worked last week.

Much as the mailing list is currently blaming Preview 14 for breakage...  I
doubt it. :-)  (The relevant code hasn't changed in ages.)

> Has there been any change in this field in preview 14? Do I miss anything?
The line where the code fails is when casting the windowService object to
Android.Views.IWindowManager. The debugger says it’s a
android.view.Window$LocalWindowManager but this type is not available.

The fix is to use Extensions.JavaCast<T>() [0]:

	var windowService =
this.GetSystemService(Android.Content.Context.WindowService);
	var windowManager =
windowService.JavaCast<Android.Views.IWindowManager>();
	// ...

The problem is that there are two type systems involved in Mono for Android,
the Android/Java type system, and the Mono type system. Mono for Android
attempts to bridge the two separate runtimes, but occasionally it breaks
down, and this is one such circumstance.

What's happening is that
GetSystemService(Android.Content.Context.WindowService) is returning an
undocumented, internal, Java type (android.view.Window$LocalWindowManager).
Because this type is undocumented, we don't (and can't) generate a managed
wrapper for the type. Consequently, when
Java.Lang.Object.GetObject<T>(IntPtr,bool) tries to find the "most derived"
wrapper type, all it can find is Java.Lang.Object [1], and thus
`windowService.GetType().FullName` is Java.Lang.Object.

Java.Lang.Object can't be cast to an IWindowManager interface, which is why
your `as IWindowManager` returns null.

The correct fix is to use the Extensions.JavaCast<T>() extension method,
which will perform a runtime Java-VM check to see if the instance can be
cast to the IWindowManager interface, and then construct an appropriate
proxy if the runtime check succeeds.

 - Jon

[0]
http://docs.mono-android.net/index.aspx?link=M%3aAndroid.Runtime.Extensions.
JavaCast``1(Android.Runtime.IJavaObject)

[1] This is arguably a bug, as it currently only checks for types and not
implemented interfaces, but this behavior won't be changing anytime soon,
either.

_______________________________________________
Monodroid mailing list
Monodroid at lists.ximian.com

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




More information about the Monodroid mailing list