0

I'm making a game that uses both Android resource and asset folders. It works fine on my device and 90% of the other devices, but few users have had an issue where some or all of the resources and assets suddenly disappear.

I have scan.png in my res/drawable folder and I load it using a normal xml button

<Button
    android:id="@+id/scan_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentBottom="true"
    android:layout_marginLeft="4dip"
    android:layout_marginBottom="4dip"
    android:visibility="gone"
    android:background="@drawable/scan"/>

The error I get its

Caused by: java.io.FileNotFoundException: res/drawable/scan.png
    at android.content.res.AssetManager.openNonAssetNative(Native Method)
    at android.content.res.AssetManager.openNonAsset(AssetManager.java:406)
    at android.content.res.Resources.loadDrawable(Resources.java:1706)
    ... 33 more
java.io.FileNotFoundException: res/drawable/scan.png
    at android.content.res.AssetManager.openNonAssetNative(Native Method)
    at android.content.res.AssetManager.openNonAsset(AssetManager.java:406)
    at android.content.res.Resources.loadDrawable(Resources.java:1706)
    at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
    at android.view.View.<init>(View.java:1951)
    at android.widget.TextView.<init>(TextView.java:389)
    at android.widget.Button.<init>(Button.java:108)
    at android.widget.Button.<init>(Button.java:104)
    at java.lang.reflect.Constructor.constructNative(Native Method)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:415)
    at android.view.LayoutInflater.createView(LayoutInflater.java:505)
    at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:568)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:623)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:626)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:408)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
    at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:209)
    at android.app.Activity.setContentView(Activity.java:1657)
    at com.leftcorner.craftersofwar.CraftersofWar.loadMain(CraftersofWar.java:323)
    at com.leftcorner.craftersofwar.CraftersofWar.access$4(CraftersofWar.java:320)
    at com.leftcorner.craftersofwar.CraftersofWar$loadContent.onPreExecute(CraftersofWar.java:281)
    at android.os.AsyncTask.execute(AsyncTask.java:391)
    at com.leftcorner.craftersofwar.CraftersofWar$2.onGlobalLayout(CraftersofWar.java:249)
    at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:549)
    at android.view.ViewRoot.performTraversals(ViewRoot.java:1195)
    at android.view.ViewRoot.handleMessage(ViewRoot.java:1865)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3687)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
    at dalvik.system.NativeStart.main(Native Method)

where CraftersofWar.java:323 is

setContentView(R.layout.main);

Then, I load an asset runebase.png that is stored in my assets folder with

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;

InputStream is = null;
try {
    is = assets.open(imgName);

    BitmapFactory.decodeStream(is, null, options); //Returns null, sizes are in the options variable

    sourceRect.set(0, 0, options.outWidth / parts, options.outHeight);
    targetRect.set(0, 0,
            Math.round((float) sourceRect.width() * Utility.getScaleWidth() * multiplier),
            Math.round((float) sourceRect.height() * Utility.getScaleHeight() * multiplier)
    );

} catch (IOException e) {
    if(GameSettings.debug) e.printStackTrace();
    else ACRA.getErrorReporter().handleException(e);
} finally {
    if(is != null){
        try {
            is.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

and the error I get is

java.io.FileNotFoundException: runebase.png
at android.content.res.AssetManager.openAsset(Native Method)
at android.content.res.AssetManager.open(AssetManager.java:314)
at android.content.res.AssetManager.open(AssetManager.java:288)
at com.leftcorner.craftersofwar.images.StorageBitmap.initialize(StorageBitmap.java:72)
at com.leftcorner.craftersofwar.images.BitmapHandler.initialize(BitmapHandler.java:84)
at com.leftcorner.craftersofwar.CraftersofWar$loadContent.onPreExecute(CraftersofWar.java:279)
at android.os.AsyncTask.execute(AsyncTask.java:391)
at com.leftcorner.craftersofwar.CraftersofWar$2.onGlobalLayout(CraftersofWar.java:249)
at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:549)
at android.view.ViewRoot.performTraversals(ViewRoot.java:1195)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1865)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
at dalvik.system.NativeStart.main(Native Method)

where StorageBitmap.java:72 is

is = assets.open(imgName);

I only know that these errors have happened on LG optimus l7 with Android version 4.0.3 and Samsung Galaxy Y (GT-S5360) with Android version 2.3.6. However, it appears that 2,40% of my users have Galaxy Y and only one has encountered the error so far.

I have unzipped the .apk that I uploaded to Google Play and it contains all the assets and resources.

Results from my discussion with Boris Strandjev:

  • I have correct drawable folders and the images don't appear in wrong folders
  • The game works flawlessly when deployed on an emulator with roughly the same specs as Galaxy Y
  • SD lock should not be the cause
  • Screen locks and sleep mode should not be the source of the problem
  • Limited memory on a specific device can be the problem, but this is hard to prove

Similar questions here at StackOverflow:

Weird FileNotFoundException exception from Android app in the wild

Strange exception about resource not found

Community
  • 1
  • 1
Finnboy11
  • 986
  • 2
  • 15
  • 34
  • How big is the runebase.png? Do you use any fragmentation folders, like drawable-hdpi? – Boris Strandjev Jan 04 '14 at 10:47
  • runebase.png is 120x120 and i do have fragmentation folders, but most of them are empty. I don't want Android to automatically scale my resources. – Finnboy11 Jan 04 '14 at 11:39
  • Both the problematic devices are ldpi in pixel density. Please make sure that the resources that the system fail to find are not declared in any fragmentation folder. I presume that you have not especially created folder drawable-ldpi? – Boris Strandjev Jan 04 '14 at 11:48
  • I have not created that folder and it only contains my game icon. These resources aren't in any of the other fragmentation folders either. – Finnboy11 Jan 04 '14 at 11:49
  • Why don't you try to run one lint scan on your application? It will help you identify the resource errors quite faster? Keep in mind that lint by default skips checking the ldpi resources as per `Low density is not really used much anymore, so this check ignores the ldpi density. To force lint to include it, set the environment variable ANDROID_LINT_INCLUDE_LDPI=true. For more information on current density usage, see http://developer.android.com/resources/dashboard/screens.html` – Boris Strandjev Jan 04 '14 at 11:53
  • I ran a lint scan. The only related issues that came out are "Not targeting the latest versions of Android" and "Found bitmap drawable res/drawable/scan.png in densityless folder" – Finnboy11 Jan 04 '14 at 12:12
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/44494/discussion-between-boris-strandjev-and-finnboy11) – Boris Strandjev Jan 04 '14 at 12:26
  • Um, why are you changing the layout (`setContentView()`) in `onGlobalLayout()` callback? – laalto Jan 04 '14 at 14:01
  • I call my setContentView() in the onPreExecute() of an AsyncTask before I load my assets in the doInBackground(Void... params). I launch this AsyncTask with OnGlobalLayoutListener which I use to measure the screen using an empty layout. – Finnboy11 Jan 04 '14 at 14:04

0 Answers0