Bug 17074 - Managed type does not match native type
Summary: Managed type does not match native type
Status: RESOLVED DUPLICATE of bug 7459
Alias: None
Product: Android
Classification: Xamarin
Component: Bindings ()
Version: 4.10.1
Hardware: PC Mac OS
: --- normal
Target Milestone: ---
Assignee: Atsushi Eno
Depends on:
Reported: 2014-01-06 13:48 UTC by Brett
Modified: 2014-01-08 12:47 UTC (History)
2 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Brett 2014-01-06 13:48:51 UTC
Using the V7 support component, the value returned from IMenuItem.ActionView can have a managed type that does not match the java object it wraps.

Steps to reproduce:

Add a search menu item to the action bar:


in your Fragment's (or Activity's) OnCreateOptionsMenu(IMenu menu, MenuInflater inflater) method, attempt to get the item's ActionView and cast it to SearchView:

 var searchEntry = menu.FindItem(Resource.Id.menuitem_search_view);
 var searchView = (global::Android.Support.V7.Widget.SearchView)searchEntry.ActionView;

The above crashes with an invalid cast exception. Inspecting the ActionView instance reveals that the java type is the expected type, but the managed type is LinearLayout.

I have worked around this for now by creating a SearchView subclass that exposes the (IntPtr, JniHandleOwnership) ctor, and pass ActionView.Handle to it. This allows me to call the SearchView methods I need, but is hacky at best.
Comment 1 Brett 2014-01-07 18:45:49 UTC
Similarly the following returns an unexpected type:


returns a type of Android.Support.V4.View.ActionProviderInvoker which is not cast-able to something like Android.Support.V7.Widget.ShareActionProvider

It seems that there are some major problems with the Menu compatibility classes.
Comment 2 Bill Holmes 2014-01-07 22:24:39 UTC
Hey Brett,

The android team would know best, however it will work if you use the JavaCast method.

using Java.Interop;

searchEntry.ActionView.JavaCast <Android.Support.V7.Widget.SearchView> ();

Also to be consistent with Android Support libraries you should use MenuItemCompat.GetActionView.

var searchEntry = menu.FindItem(Resource.Id.menuitem_search_view);
var searchView = MenuItemCompat.GetActionView (searchEntry).JavaCast <Android.Support.V7.Widget.SearchView> ();
Console.WriteLine (searchView.GetType ());

GetActionProvider will work the same way.  

var shareEntry = menu.FindItem(Resource.Id.menuitem_share_view);
var actionProvider = MenuItemCompat.GetActionProvider (shareEntry).JavaCast <Android.Support.V7.Widget.ShareActionProvider> ();
Console.WriteLine (actionProvider.GetType ());

Maybe I can add some generic overloads in the next version of the support libraries.  That should clean up the syntax a bit.  

MenuItemCompat.GetActionView<Android.Support.V7.Widget.SearchView> (searchEntry);
Comment 3 Atsushi Eno 2014-01-08 05:40:04 UTC
(xams: To my understanding from our discussion, it is entirely a duplicate bug, but if it's not the case add more comments.)

*** This bug has been marked as a duplicate of bug 7459 ***
Comment 4 Brett 2014-01-08 12:47:01 UTC
Yeah, I should mention that I did refactor to use MenuItemCompat, et al (the issue still exists, but I'm doing the *right thing* now).

Thanks for the JavaCast tip, I'll try that, it's better than my hacky subclass solution.