Java中的Creator是什么以及如何将其转换为C#

时间:2018-11-09 05:45:07

标签: java c# android xamarin xamarin.android

我正在将代码从Java转换为C#/ Xamarin,但是我无法理解下面提到的代码

public static class GraphicPath implements Parcelable
{
    protected GraphicPath(Parcel par)
    {
        int size=in.readInt();
        int[] x=new int[size];
        int[] y=new int[size];
        in.readIntArray(x);
        in.readIntArray(y);
        pathX=new ArrayList<>();
        pathY=new ArrayList<>();

        for (int i=0;i<x.length;i++){
            pathX.add(x[i]);
        }

        for (int i=0;i<y.length;i++){
            pathY.add(y[i]);
        }
    }

    //Unable to understand and translate the below code.
    public static final Creator<GraphicPath> CREATOR = new Creator<GraphicPath>() {
       @Override
        public GraphicPath createFromParcel(Parcel in) {
            return new GraphicPath(in);
        }

        @Override
        public GraphicPath[] newArray(int size) {
            return new GraphicPath[size];
        }
   };
}

它是什么,如何将其转换为C#,以及如何将Java处理程序代码转换为C#?处理程序是线程吗?如何将以下处理程序转换为C#

 Handler handler = new Handler(Looper.getMainLooper());

 new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    startCapture();
                }
            },1000);

handler.post(new Runnable() {
            @Override
            public void run() {
                toCapture();
            }
        });
        return;

转换后的C#代码给出错误,该C#代码实现IParcelable接口,并且其中没有Creator。

 public class GraphicPath : IParcelable
{
    protected GraphicPath(Parcel par)
    {
        int size =par.ReadInt();
        int[] x = new int[size];
        int[] y = new int[size];
        par.ReadIntArray(x);
        par.ReadIntArray(y);
        pathX = new List<int>();
        pathY = new List<int>();

        for (int i = 0; i < x.Length; i++)
        {
            pathX.Add(x[i]);
        }

        for (int i = 0; i < y.Length; i++)
        {
            pathY.Add(y[i]);
        }
    }

    //Red lines here
    public static Creator<GraphicPath> CREATOR = new Creator<GraphicPath>() {

        //paste here
    };
  }

2 个答案:

答案 0 :(得分:0)

Creator用于Parcelable,Parcelable用于序列化类,以通过Intent在活动之间传递它们,因此您必须遵循本文档https://developer.xamarin.com/api/type/Android.OS.Parcelable/  如何在Xamarin中使用它们

public class MyParcelable implements Parcelable {
     private int mData;

     public int describeContents() {
         return 0;
     }

     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mData);
     }

     public static final Parcelable.Creator<MyParcelable> CREATOR
             = new Parcelable.Creator<MyParcelable>() {
         public MyParcelable createFromParcel(Parcel in) {
             return new MyParcelable(in);
         }

         public MyParcelable[] newArray(int size) {
             return new MyParcelable[size];
         }
     };

     private MyParcelable(Parcel in) {
         mData = in.readInt();
     }
 }

对于处理程序,您还必须查看此文档https://developer.xamarin.com/api/type/Android.OS.Handler/

答案 1 :(得分:-1)

我已经在ViewPagerIndicator端口中完成了此操作,以保存状态:https://github.com/Cheesebaron/ViewPagerIndicator/blob/master/Library/CirclePageIndicator.cs#L535

因此,您可以创建自己的创作者:

public class GraphicPathCreator : Java.Lang.Object, IParacleableCreator
{
    public Java.Lang.Object CreateFromParcel(Parcel source)
    {
        return new GraphicPath(source);
    }

    public Java.Lang.Object[] NewArray(int size)
    {
        return new GraphicPath[size];
    }
}

然后,您可以像这样定义CREATOR

[ExportField("CREATOR")]
public static GraphicPathCreator Creator()
{
    return new GraphicPathCreator();
}

这里的ExportField很重要。它将您的方法在Android Callable Wrappers中显示为CREATOR

要将其与您的GrapicPath结合使用,看起来会像这样:

public static class GraphicPath : BaseSavedState
{
    public List<int> PathX { get; private set; }
    public List<int> PathY { get; private set; }

    public GraphicPath(IParcelable superState)
        : base(superState)
    {
    }

    public GraphicPath(Parcel parcel) : base(parcel)
    {
        var size = parcel.ReadInt();
        int[] x = new int[size];
        int[] y = new int[size];
        parcel.ReadIntArray(x);
        parcel.ReadIntArray(y);
        PathX = new List<int>(x);
        PathY = new List<int>(y);
    }

    public override void WriteToParcel(Parcel dest, ParcelableWriteFlags flags)
    {
        base.WriteToParcel(dest, flags);
        dest.WriteInt(PathX.Count);
        dest.WriteIntArray(PathX.ToArray());
        dest.WriteIntArray(PathY.ToArray());
    }

    // creator stuff here

对于Handlers,有几种解决方法。您可以将它们转换为C#任务,也可以保持不变,仅将它们翻译为1:1。

对于1:1转换,它们看起来像:

var handler = new Handler(Looper.MainLooper);
handler.PostDelayed(() => StartCapture(), 1000);

handler.Post(() => ToCapture());

lambda只是Action的匿名实例。