我建立一个使用定制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#重写。
谢谢你的帮助!
恭喜! 你已经打了一个漏水的抽象。 : - /
问题是这样的: 是好还是坏 ,从构造虚拟方法调用调用最衍生的方法实现。 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)
构造函数 。
该错误消息指出:
System.Exception: No constructor found for MyProject.TwoDScrollView::.ctor(System.IntPtr, Android.Runtime.JniHandleOwnership)
尝试添加一个构造像它说,看看是否有帮助:
public TwoDScrollView (IntPtr a, JniHandleOwnership b) : base (a, b) { }
我有一个自定义的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)
{
}
我用的是自定义列表视图渲染,但没有变通的工作对我来说。 但延迟base.Dispose
方法帮我解决死机,可能这给单机器人,初始化代理实例的机会。
Xamarin.Forms.Device.BeginInvokeOnMainThread(base.Dispose);
我没有看到任何崩溃了!