MonoDroid的:调用自定义视图的构造函数时错误 - TwoDScrollViewMonoDr

2019-05-14 02:34发布

我建立一个使用定制TwoDScrollView在这里找到一个Android应用程序:

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

这同一个类中,可以发现在其他一些网站引用,和其他人对堆栈溢出问关于它的问题。 我用它,我是使用Java / Eclipse中建立一个以前的Android应用程序,和我有成功。

以我目前的应用程序,我想用C#和MonoDroid的。 我决定重写在C#中的整个TwoDScrollView类。 改写它,然后在一些布局XML使用它之后,我想我的代码运行时,遇到以下情况除外:

System.NotSupportedException已经抛出。 无法从原生手柄44f4d310激活型MyProject.TwoDScrollView的实例。

System.Exception的:没有构造发现MyProject.TwoDScrollView ::构造函数(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>

每在以下链接中使用MonoDroid的布局XML自定义视图中的说明: http://docs.xamarin.com/android/advanced_topics/using_custom_views_in_a_layout

如下的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版本(你可以找到在上面的链接)。 什么可能会错误的任何想法? 我可以张贴我的TwoDScrollView的完整C#代码,如果有人想看到它。 它本质上是相同的Java代码逐位 - 除了在C#重写。

谢谢你的帮助!

Answer 1:

恭喜! 你已经打了一个漏水的抽象。 : - /

问题是这样的: 是好还是坏 ,从构造虚拟方法调用调用最衍生的方法实现。 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构造已经执行。

在单为Android,事情变得更加复杂...。 所述的Android调用包装(ACW)的构造是由Java的调用和负责创建的对等体C#实例和映射的Java实例的C#实例 。 但是 ,如果一个虚拟的方法从Java调用构造函数,则该方法将在此之前还有一个C#实例时要调用的方法出动

让有点那个水槽。

我不知道哪种方法触发场景为您的特定代码(代码片段您提供优良工程),但我们确实有它打这种情况的例子: LogTextBox 覆盖的TextView.DefaultMovementMethod属性和TextView构造函数调用getDefaultMovementMethod()方法 。 其结果是,Android的尝试调用LogTextBox.DefaultMovementMethod一个前LogTextBox实例甚至存在。

那么,是什么单为Android做什么? 单声道的Android创建的ACW,并且因此知道哪个C# 类型 getDefaultMovementMethod()方法应该授予。 它所不拥有的是一个实例,因为一个尚未创建。 所以单为Android创建合适类型的实例......通过(IntPtr, JniHandleOwnership)构造函数,如果此构造函数无法找到产生错误。

一旦(在这种情况下) TextView构造函数完成执行后, LogTextBox的ACW构造函数会执行,在这一点单为Android会去‘啊哈!我们已经创建了这个Java实例的C#实例’, 然后将调用对已创建的实例适当的构造。 这意味着单个实例,两个构造函数将被执行:在(IntPtr, JniHandleOwnership)构造函数 ,和(后下)各(Context, IAttributeSet, int)构造函数 。



Answer 2:

该错误消息指出:

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

尝试添加一个构造像它说,看看是否有帮助:

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



Answer 3:

我有一个自定义的ImageView和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)
        {
        }


Answer 4:

我用的是自定义列表视图渲染,但没有变通的工作对我来说。 但延迟base.Dispose方法帮我解决死机,可能这给单机器人,初始化代理实例的机会。

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

我没有看到任何崩溃了!



文章来源: MonoDroid: Error when calling constructor of custom view - TwoDScrollView