Forum Xamarin.Android

Inheriting from FileInputStream.

ShaunMcDonnellShaunMcDonnell USMember
edited December 2012 in Xamarin.Android

I have a class that inherits from Java.IO.FileInputStream. It looks something like this:

public class DeviceInputStream : FileInputStream
{
    private FileDescriptor descriptor = null;
    private byte currentValue;

    public DeviceInputStream(FileDescriptor fd) : base(fd)
    {
        descriptor = fd;
    }

    public DeviceInputStream(File file) : base(file){}

    public DeviceInputStream(string fileName):base(fileName){}

    public override int Read()
    {
        int byteRead = base.Read();
        currentValue = (byte) byteRead;
        return byteRead;
    }

    public byte CurrentValue
    {
        get { return currentValue; }
    }
}

However, when I compile this I get the following error:

unreported exception FileNotFoundException; must be caught or declared to be thrown super (p0); DeviceInputStream.java:20

Any ideas as to what might be causing this problem? Thanks.

-Shaun

Posts

  • JonathanPryorJonathanPryor USXamarin Team Xamurai

    Ouch. Java interop fail. :-(

    Any ideas as to what might be causing this problem? Thanks.

    At build time, Android Callable Wrappers (ACWs) are generated for each Java.Lang.Object subclass, which includes our DeviceInputStream type:

    public class DeviceInputStream
        extends java.io.FileInputStream
        implements
            mono.android.IGCUserPeer
    {
        static final String __md_methods;
        static {
            __md_methods = 
                "n_read:()I:GetReadHandler\n" +
                "";
            mono.android.Runtime.register ("Scratch.ContentProvidersHateApplications.DeviceInputStream, Scratch.ContentProvidersHateApplications, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", DeviceInputStream.class, __md_methods);
        }
    
    
        public DeviceInputStream (java.io.File p0)
        {
            super (p0);
            if (getClass () == DeviceInputStream.class)
                mono.android.TypeManager.Activate ("Scratch.ContentProvidersHateApplications.DeviceInputStream, Scratch.ContentProvidersHateApplications, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", "Java.IO.File, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=c4c4237547e4b6cd", this, new java.lang.Object[] { p0 });
        }
    
    
        public DeviceInputStream (java.io.FileDescriptor p0)
        {
            super (p0);
            if (getClass () == DeviceInputStream.class)
                mono.android.TypeManager.Activate ("Scratch.ContentProvidersHateApplications.DeviceInputStream, Scratch.ContentProvidersHateApplications, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", "Java.IO.FileDescriptor, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=c4c4237547e4b6cd", this, new java.lang.Object[] { p0 });
        }
    
    
        public DeviceInputStream (java.lang.String p0)
        {
            super (p0);
            if (getClass () == DeviceInputStream.class)
                mono.android.TypeManager.Activate ("Scratch.ContentProvidersHateApplications.DeviceInputStream, Scratch.ContentProvidersHateApplications, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", "System.String, mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", this, new java.lang.Object[] { p0 });
        }
    
    
        public int read ()
        {
            return n_read ();
        }
    
        private native int n_read ();
    
        /* ... */
    }
    

    Since ACWs are Java code, they need to be valid Java code. Unfortunately, in this circumstance they're not, because the super(p0) invocation in e.g. the DeviceInputStream(String) constructor is FileInputStream(String), which throws a FileNotFoundException.

    Since the DeviceInputStream(String) constructor invokes a method which may thrown an exception, DeviceInputStream(String) must either contain a throws clause or have a try/catch block around the super(p0) statement. Neither happens, hence the compiler error.

    Unfortunately, there is no workaround at this time; there isn't a way to add a throws to the ACW on constructor bodies, and there is no other way to customize the ACW's constructor, so you're stuck. :-(

    Support to extend ExportAttribute so that this could work has been filed at bug 8754.

  • Thanks for the answer, much appreciated.

Sign In or Register to comment.