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 #.

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

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

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

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

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

 Renaud20 дек. 2017 г., 15:41
У меня была такая же проблема с BroadcastReceiver для Bluetooth. Я должен был правильно отменить его регистрацию, но спасибо, @jpobst, это мне очень помогает разобраться.
 David15 мая 2012 г., 06:11
Ты хочешь попробовать логичный ответ? ;-) Так что, да, ваше предложение действительно решает проблему, как описано в моем первоначальном вопросе (например: он избавляется от сообщения об ошибке, но поведение приложения по-прежнему неверно - представление не отображается), но это не решает проблему, которая лежит в основе проблемы: почему он вообще ищет этот конструктор? Конструктор, который он вызывает, не является одним из стандартных конструкторов для класса пользовательского представления Android. Стандартные конструкторы, которые предполагается создать, - это те, которые я перечислил выше.
 SubqueryCrunch18 апр. 2016 г., 10:39
У меня была такая же проблема с созданием класса, и это решило мою проблему.
 jonp15 мая 2012 г., 17:12
@ Дэвид: Почему он ищет(IntPtr, JniHandleOwnership) конструктор в первую очередь? Утечка абстракций. Смотрите мой ответ: Stackoverflow.com / а / 10603714/83444

и ответ на 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)
        {
        }

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

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

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

 Joyce de Lanna02 мар. 2018 г., 22:36
где ты это написал?
 Joyce de Lanna05 мар. 2018 г., 16:03
Кажется, это решило мою проблему !! Я столько искал и ничего не мог решить ... спасибо !!!
 Joyce de Lanna23 мар. 2018 г., 14:41
Это случилось снова ... Я не знаю, что делать дальше
 Zafar Ameem03 мар. 2018 г., 23:47
Внутри вашего класса ListViewRenderer переопределите метод Dispose и вызовите base.Dispose (удаление), как указано выше
Решение Вопроса

Проблема в следующем:для лучшего или худшег, вызовы виртуальных методов из конструкторов вызывают наиболее производную реализацию метода. В этом отношении 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) конструктор.

 rideintothesun15 нояб. 2017 г., 14:36
Кто-нибудь знает, как узнать, где в первую очередь вызывается удаленное представление?
 jonp07 мар. 2016 г., 18:54
Нет, мы не должны добавлять этот конструктор по умолчанию, потому что он будет скрыть ошибки. Если вы получаетеNo constructor found... сообщение, это означает, что сопоставленный экземпляр был преждевременно собранный, что означает либо естьDispose() звонить, которого там не должно быть, или есть ошибка GC, или что-то еще, что очень важно и не должно быть скрыто ™. Вы должны пониматьЗаче исключение происходит, чтобы культ груза не «решил проблему».
 mayabelle27 апр. 2016 г., 19:43
Мне также интересно узнать об ошибках Xamarin.Forms.Platform.Android.Platform + DefaultRenderer. Есть ли способ добавить конструктор, о котором они просят?
 Mark1342606 мар. 2016 г., 17:04
@ jonp Разве Xamarin не должен добавить этот конструктор во все классы по умолчанию? Программисты могут предоставить это в своем собственном коде, но у Mono и Forms также есть проблемы. Я продолжаю получатьNo constructor found for Java.Lang.Thread+RunnableImplementor и дляXamarin.Forms.Platform.Android.Platform+DefaultRenderer
 Mark1342625 апр. 2016 г., 00:38
@ jonp Могу ли я что-нибудь сделать для предотвращения тех исключений, о которых я упоминал ранее? На данный момент я чувствую себя невежественным. : | Для средств визуализации представлений, упомянутых другими людьми, кажется, что легко предоставить дополнительный конструктор, но я понятия не имею, чтоJava.Lang.Thread+RunnableImplementor а такжеXamarin.Forms.Platform.Android.Platform+DefaultRenderer являются

Ваш ответ на вопрос