What is Creator in Java and how to Translate it to C#

I am translating a code from Java to C#/Xamarin, but i am unable to understand the below mentioned code

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];
        }
   };
}

what is it and how to convert it to C#, and how to translate the Java handler code to C# ? is handler a thread ? how to convert the below handlers to 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;

The converted C# code gives error, the C# code implements IParcelable interface and it doesn't have Creator in it.

 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 answers

  • answered 2018-11-09 15:14 Cheesebaron

    I've done this in my port of ViewPagerIndicator for saving state: https://github.com/Cheesebaron/ViewPagerIndicator/blob/master/Library/CirclePageIndicator.cs#L535

    So to create your own creator you would do:

    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];
        }
    }
    

    Then you can define the CREATOR like:

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

    The ExportField here is important. It exposes your method as CREATOR in the Android Callable Wrappers.

    To combine this with your GrapicPath it would look something like:

    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
    

    As for Handlers there are a couple of ways to tackle those. You can convert them to C# Task's or keep them as is and just translate them 1:1.

    For the 1:1 conversion they would look like:

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

    The lambdas are just anonymous instances of Action.

  • answered 2018-11-09 15:17 gmetax

    Creator is used for the Parcelable, Parcelable is used for serializing of class to pass them between activities via Intents, so you have to follow this documentation https://developer.xamarin.com/api/type/Android.OS.Parcelable/ how to use them in 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();
         }
     }