Bug 8162 - Assets.Open() Fails on one binary file, but not another
Summary: Assets.Open() Fails on one binary file, but not another
Status: RESOLVED UPSTREAM
Alias: None
Product: Android
Classification: Xamarin
Component: BCL Class Libraries ()
Version: 4.2.x
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2012-11-01 20:54 UTC by Jared Reed
Modified: 2013-05-23 14:07 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Project showing the problem (618.96 KB, application/x-zip-compressed)
2012-11-01 20:54 UTC, Jared Reed
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED UPSTREAM

Description Jared Reed 2012-11-01 20:54:01 UTC
Created attachment 2835 [details]
Project showing the problem

I have 2 binary files of the exact same size. I am using Assets.Open() to load them. When I call it on File A, it always loads. When I call it on File B, it always throws an exception. Whether I try to load File B first or last, it always fails. It throws a Java.IO.IOException with no message.

It is almost as if Assets.Open() is looking at the contents of the binary file and deciding it will not load it.

I have tested this on a Nexus 7 running Android 4.1.2, and a Droid Incredible running Android 2.3.4. Same problem on both.

I have attached a project that reproduces the issue.
Comment 1 Jonathan Pryor 2012-11-02 14:06:33 UTC
Oddly, it works here on a Galaxy Nexus running Android 4.1.2.

I expect it to fail on Android <= 2.2 (iirc), because they don't support uncompressing files larger than 1MB. That's not the case on Android 2.3 or Android 4.1...
Comment 2 Atsushi Eno 2012-11-02 14:17:19 UTC
I could reproduce it with Nexus 7 (Android 4.1.2), MfA 4.2.8 beta on Mac. Output from slightly modified code to print full stack trace:

Forwarding debugger port 8893
Forwarding console port 8894
Detecting existing processLoaded assembly: /data/data/AndroidReadFileException.AndroidReadFileException/files/.__override__/AndroidReadFileException.dll
Loaded assembly: Mono.Android.dll [External]
Loaded assembly: System.Core.dll [External]
Loaded assembly: MonoDroidConstructors [External]

WARNING: The runtime version supported by this application is unavailable.
Using default runtime: v2.0.50727
GREF GC Threshold: 46800
Error reading asset data
Unable to access asset data: -1
Java.IO.IOException: Exception of type 'Java.IO.IOException' was thrown.
  at Android.Runtime.JNIEnv.CallIntMethod (IntPtr jobject, IntPtr jmethod, Android.Runtime.JValue[] parms) [0x00024] in /Users/builder/data/lanes/monodroid-mac-monodroid-4.2-series/658a67dc/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:269 
  at Java.IO.InputStream.Read (System.Byte[] b, Int32 offset, Int32 length) [0x00045] in /Users/builder/data/lanes/monodroid-mac-monodroid-4.2-series/658a67dc/source/monodroid/src/Mono.Android/platforms/android-8/src/generated/Java.IO.InputStream.cs:249 
  at Android.Runtime.InputStreamInvoker.Read (System.Byte[] buffer, Int32 offset, Int32 count) [0x00000] in /Users/builder/data/lanes/monodroid-mac-monodroid-4.2-series/658a67dc/source/monodroid/src/Mono.Android/src/Runtime/InputStreamInvoker.cs:30 
  at System.IO.Stream.CopyTo (System.IO.Stream destination, Int32 bufferSize) [0x00000] in <filename unknown>:0 
  at System.IO.Stream.CopyTo (System.IO.Stream destination) [0x00000] in <filename unknown>:0 
  at AndroidReadFileException.Activity1.ReadFileToMemoryStream (System.String filename) [0x00013] in /Users/atsushi/Desktop/AndroidReadFileException/AndroidReadFileException/Activity1.cs:32 
  --- End of managed exception stack trace ---
java.io.IOException: 
	at android.content.res.AssetManager.readAsset(Native Method)
	at android.content.res.AssetManager.access$700(AssetManager.java:35)
	at android.content.res.AssetManager$AssetInputStream.read(AssetManager.java:576)
	at androidreadfileexception.Activity1.n_onCreate(Native Method)
	at androidreadfileexception.Activity1.onCreate(Activity1.java:28)
	at android.app.Activity.performCreate(Activity.java:5008)
	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
	at android.app.ActivityThread.access$600(ActivityThread.java:130)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loop(Looper.java:137)
	at android.app.ActivityThread.main(ActivityThread.java:4745)
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:511)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
	at dalvik.system.NativeStart.main(Native Method)
Comment 3 Jonathan Pryor 2012-11-02 14:27:53 UTC
What jumps out at me:

> Unable to access asset data: -1

Web search suggests...not compressing the assets

http://pompidev.net/2012/10/27/unable-to-access-asset-data-1-and-compressed-assetsandroid/

That's not a very nice option, though it would work...
Comment 4 Jared Reed 2012-11-02 14:51:46 UTC
Regarding the two images I am loading: The broken one is a 1024x1024 image. The working one is a 2048x512 image.

Funny thing is I can workaround the problem by changing the size of my image.

Thanks for the article url. It seems like this may be the same or similar issue. He solved it with code, but mentioned that it could be solved with xml config files. I'll look around for the xml config option.

He mentioned that since the file was compressed, you couldn't read it that way. I wonder how you would read a file that is compressed.

Anyway, thanks for the help!
Comment 5 Jonathan Pryor 2012-11-02 15:04:17 UTC
> I wonder how you would read a file that is compressed

On older Android platforms (with the aforementioned 1MB limit when decompressing assets), the answer is "you don't." Instead, you _store_ the file into the .apk uncompressed. You can specify which file extensions shouldn't be compressed in the Project Properties, e.g. in MonoDevelop's Project Options dialog, go to the Build > Mono for Android Build panel, and enter ".xnb" in the "Leave the following resource extensions uncompressed" textbox.
Comment 6 Jared Reed 2012-11-02 15:11:26 UTC
Wow, that is easy. :) Thanks for all the help.
Looks like if I target Android 2.3, there isn't a problem. I'll do that and add the .xnb extension to the "don't compress" list.
Thanks for the help!
Comment 7 Atsushi Eno 2012-11-13 03:36:12 UTC
I wonder if this is an upstream (aapt) bug or not and we should close this bug as such.
Comment 8 Jonathan Pryor 2012-11-13 10:20:29 UTC
It's probably an upstream bug, but to verify that we'd have to write a Java app...