15 мая 2012 г., 03:17 отDavid

MonoDroid: ошибка при вызове конструктора пользовательского представления - TwoDScrollView

Я создаю приложение для Android, которое использует пользовательский TwoDScrollView, найденный здесь:

http: //blog.gorges.us/2010/06/android-two-dimensional-scrollview

Этот же класс можно найти на нескольких других веб-сайтах, а другие в Stack Overflow задают вопросы по этому поводу. Я использовал его в предыдущем приложении Android, которое создавал с использованием Java / Eclipse, и у меня был успех.

С моим текущим приложением я хотел использовать C # и MonoDroid. Я решил переписать весь класс TwoDScrollView в C #. После его переписывания и последующего использования в каком-то макете XML я получаю следующие исключения при попытке запустить мой код:

System.NotSupportedException было сгенерировано. Невозможно активировать экземпляр типа MyProject.TwoDScrollView из собственного дескриптора 44f4d310.

System.Exception: не найден конструктор для MyProject.TwoDScrollView ::. Ctor (System.IntPtr, Android.Runtime.JniHandleOwnership) ...... с дополнительным текстом, который следует ....

Мой макет XML выглядит следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

<myproject.TwoDScrollView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

</myproject.TwoDScrollView>

</RelativeLayout>

Выполните инструкции по приведенной ниже ссылке на использование пользовательских представлений в макете XML в MonoDroid:http: //docs.xamarin.com/android/advanced_topics/using_custom_views_in_a_layou

Конструкторы класса TwoDScrollView выглядят следующим образом:

public TwoDScrollView(Context context) 
    : base(context)
{
    initTwoDScrollView();
}

public TwoDScrollView(Context context, IAttributeSet attrs) 
    : base(context, attrs)
{
    initTwoDScrollView();
}

public TwoDScrollView(Context context, IAttributeSet attrs, int defStyle) 
    : base(context, attrs, defStyle)
{
    initTwoDScrollView();
}

В версии C # существуют те же конструкторы, что и в версии Java (которую вы можете найти по ссылке выше). Есть идеи, что может пойти не так? Я могу опубликовать полный код C # моего TwoDScrollView, если кто-то захочет его увидеть. По сути, это то же самое, что битовый код Java, за исключением того, что переписан на C #.

Спасибо за любую помощь!

Ответы на вопрос(0)

15 мая 2012 г., 01:26 отjpobst

System.Exception: No constructor found for MyProject.TwoDScrollView::.ctor(System.IntPtr, Android.Runtime.JniHandleOwnership)

Попробуйте добавить конструктор, как он говорит, и посмотрите, поможет ли это:

public TwoDScrollView (IntPtr a, JniHandleOwnership b) : base (a, b) { }

11 мар. 2015 г., 02:10 отAmir Kotb

и ответ на jpobst определенно решил проблему полностью:

public CircularImageView(Context context)
            :base(context) 
        {

            init (context, null, 0);
        }

        public CircularImageView(Context context, IAttributeSet attrs)
            : base(context, attrs)
        {
            init (context, attrs, Resource.Attribute.circularImageViewStyle);
        }

        public CircularImageView(Context context, IAttributeSet attrs, int defStyle)
            :base(context, attrs, defStyle)
        {

            init(context, attrs, defStyle);
        }
        public CircularImageView (IntPtr a, JniHandleOwnership b) : base (a, b)
        {
        }
18 янв. 2018 г., 18:00 отZafar Ameem

но ни один из обходных путей не помог мне. Но затягиваяbase.Disposeетод @ помог мне исправить ошибку, возможно, это дает моно Android возможность инициализировать экземпляр прокси.

Xamarin.Forms.Device.BeginInvokeOnMainThread(base.Dispose);

Я сейчас не вижу сбоев!

15 мая 2012 г., 14:11 отJonas

Проблема в следующем:для лучшего или худшег, вызовы виртуальных методов из конструкторов вызывают наиболее производную реализацию метода. В этом отношении C # такой же, как Java; рассмотрим следующую программу:

using System;

class Base {
    public Base ()
    {
        Console.WriteLine ("Base..ctor");
        M ();
    }

    public virtual void M ()
    {
        Console.WriteLine ("Base.M");
    }
}

class Derived : Base {

    public Derived ()
    {
        Console.WriteLine ("Derived..ctor");
    }

    public override void M ()
    {
        Console.WriteLine ("Derived.M");
    }
}

static class Demo {
    public static void Main ()
    {
        new Derived ();
    }
}

При запуске вывод:

Base..ctor
Derived.M
Derived..ctor

ЭтоDerived.M()етод @ вызывается доDerived конструктор выполнен.

В Mono для Android все становится сложнее. Android Callable Wrapper (ACW)онструктор @ вызывается Java и отвечает за созданиеpeer C # экземпляр и сопоставление экземпляра Java с C # экземпляром. Тем не мени, если виртуальный метод вызывается из конструктора Java, то метод будет отправлен до того, как появится экземпляр C # для вызова метода!

Давай потонем немного.

Я не знаю, какой метод запускает сценарий для вашего конкретного кода (предоставленный вами фрагмент кода работает нормально), но у нас есть пример, который подходит к этому сценарию: LogTextBox Переопределяет the TextView.DefaultMovementMethod свойство, аTextView конструктор вызываетgetDefaultMovementMethod() метод. В результате Android пытается вызватьLogTextBox.DefaultMovementMethod передLogTextBox Экземпляр даже существует.

Так что же делает Mono для Android? Mono для Android создал ACW и, следовательно, знает, какой C #ти thegetDefaultMovementMethod()етод @ должен быть делегирован. Чего у него нет, так это экземпляра, потому что он еще не создан. Таким образом, Mono для Android создает экземпляр соответствующего типа ... через(IntPtr, JniHandleOwnership) конструктор и генерирует ошибку, если этот конструктор не может быть найден.

Как только (в данном случае)TextView конструктор завершает выполнение,LogTextBoxонструктор ACW @ будет выполнен, после чего Mono для Android будет выглядеть так: «ага! мы уже создали экземпляр C # для этого экземпляра Java», и будеттогд вызвать соответствующий конструктор для уже созданного экземпляра. Это означает, что для одного экземпляра будут выполнены два конструктор(IntPtr, JniHandleOwnership) конструктор и (позже)(Context, IAttributeSet, int) конструктор.

ВАШ ОТВЕТ НА ВОПРОС