I created an app with images, and I added them via Android Icon Set wizard. The wizard created 3 versions for the images - mdpi, hdpi, xhdpi.
I published my app on google play, and I got a crash reports from users that have ldpi screen. The exception was Caused by: android.content.res.Resources$NotFoundException: File from drawable resource ID #0x7f02007f.
The drawable was exists in mdpi, hdpi and xhdpi and the app worked to the rest of the users.
So I guess that the problem was that the drawable dose not exists in its ldpi version.
So my questions are:
1) Is there any way to say to the app to auto scale the mdpi drawables instead of crashing?
2) For support ldpi screens, must I edit the images to ldpi size?
Thanks.
This is a common error of different densities management, so these are the answers to your questions.
1.- No, in the way your assets are stored but Yes, "ONLY if your asset is in a lower hierarchy of your current density" for example: If you have assets in drawable(default non specific density) and drawable-ldpi AND you run the app in a Medium Density Device, the OS will try to resize your Images from -ldpi to your density (if using dps in the Image but will cost memory). The way the OS handles the Assets is the following:
Lets say you have:
res-
-drawable
-icon.png
-drawable-ldpi
-icon.png
-drawable-mdpi
-icon.png
If you are running an app in a HIGH Density device the OS first will try to find your asset in drawable-hdpi, but since it doesn't exist it will start going down the hierarchy until it finds it, so in this case it will not find it in drawable-hdpi but will find it in drawable-mdpi and will use that one to populate, everything will be fine but will cost in memory the difference of densities in the assets.
Now the exact error you have comes to play when the OS goes down the assets folder hierarchy and goes until the end and do not find anything for example:
Lets say you have:
res-
-drawable-hdpi
-icon.png
If you run this app, in HIGH Desnity Device it will run perfect, because will find the asset in the first try and will never go down the hierarchy, same case for Extra High Density Device because if it doesnt find it in drawable-xhdpi it will find it in the next step when going down the hierarchy to drawable-hdpi and will work just fine, but for MEDIUM Density, however, first it will try to find it in drawable-mdpi since its not there, will go down and try to find it in drawable-ldpi no luck either so it will go to the "default (drawable)" which is a good practice to contain all the assets in an average size to at least make the app look blurry than crashing, since the OS will not find the Asset either BOOOM no resource found, there you have your exception, this mechanism applies for pretty much any resource in Android
2.- YES, you must create your assets in ldpi and store them either in drawable-ldpi or drawable(default - no density) in order to make it look good.
All this information has been taken out of a book and if you still have doubts, create an empty Android Project in Eclipse and notice how the SDK creates one icon_launcher.png img in each density with a specific size to handle exactly this issue. As a recommendation in my experience I've found useful to always take care of all the densities, but more important having all my assets with an average density/quality in the default folder to avoid this exact issue in case you could forget one density during development, is better a blurry asset than a crash.
Hope this Helps.
Regards!
Is there any way to say to the app to auto scale the mdpi drawables instead of crashing?
This happens automatically, unless the maker of the firmware (device manufacturer or ROM modder) screwed it up.
For support ldpi screens, must I edit the images to ldpi size?
No.
I would look up 7f02007f in the R.java associated with your production code base and make sure that it is what you think it is. Bear in mind that these numbers get regenerated on every compile. Perhaps this is a case where there simply is no drawable resource for this number, in any density, because R.java was out of sync with the actual resource packaging. To avoid this problem, do a clean build (e.g., Project > Clean inside of Eclipse) as part of making the production APK.
Related
I'm getting quite a few crashes on a live app.
Fatal Exception: android.content.res.Resources$NotFoundException
Resource ID #0x7f080389
The resource exists.
It is a PNG and it's set using.
icon.setImageResource(a.icon);
where a.icon is an int with the id of the image required. I'm 100% sure the value here is fine.
There is no obvious pattern in regard to device and operating system. With the same phone and os version in testing and most live users everything is fine.
The app is distributed on Play Store using a package.
My current theory is that some people are getting the app via some other place (the app is not available everywhere) and the APK they are trying to use does not match the screen density of their phone.
Is this reasonable (and can I prevent this) or is there another possibility?
Cheers.
This exception is coming because image is present but not for all the resolutions.
Device will check the image in all the drawable folders which are equal or lesser resolution to resolution of current device.
Various screen resolutions are mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi.
Example: if you image is present in drawable-xxhdpi folder and device is of resolution xhdpi. Then it will check for image only in drawable-xhdpi, drawable-hdpi, drawable-mdpi and default drawable folder and may result to resource not found exception.
Hence you should add image to all the various resolution folders as per the quality. xxxhdpi should have sharp and high quality images.
Also, it is recommended to add default images in the default drawable folder to avoid any resource not found exceptions.
Hope it helps.
Released the app as an APK. No issues at all. Definitely something not quite right with the package splitting.
In this year Google annoucement new app bunle for android or Google
Play users.
Good, but already know it we are using still xdpi, mdpi, xxdpi, resource files.
So, app bundle split your images, language but if we delete xdpi, mdpi, xxdpi files and we protect xxxdpi resource files and we reduced %40 app size.
I mean if you delete other resource images (in res folder) except xxxdpi,
will the app bundle be a problem for devices?
If you provide only the images in the xxxhdpi density, your app will run slower on some devices since the Android platform will need to scale down the images on the fly before rendering them. It also takes CPU thus to perform the scaling, thus taking on the battery of the users.
So although this is an option that is perfectly compatible with the Android App Bundle (nothing will crash -- all the users will get your xxxhdpi resources), it will have negative consequences for your users, so you shouldn't do it.
**anydpi**: These resources take precedence in any dpi. So even if you have mipmap-hdpi or mipmap-mdpi matching with current devices density, resource from mipmap-anydpi will always be picked up.
I have been using it for adaptive launcher icon for my apps and it generates the xml and there is no need for any other dpi dependent drawables.
You can get more information by visiting these links.
Anydpi and anydpi-v26
Image asset studio
nodpi vs anydpi
Adaptive icons and more
Couldn't put in comment so adding it here
Switched my eclipse project to Android studio. I was maintaining resources under drawable-mdpi folder only. Now in studio the preview of XML loads images correctly. However when I run the app in a device with resolution higher than mdpi the app crashes, shows error inflating binary XML.
After a long analysis I found the issue that the device was trying to load images from its corresponding density folder which is not available. So I created the folder drawable-xhdpi and put images in that folder. Now the app works fine.
Why android studio can't pick image from other density drawable folder and resize which is possible by eclipse. I can't maintain 5 different drawable folders because there are lots of images.
you have to add "drawable-hdpi" resource directory and paste all the hdpi resources there because currently 70% android devices supports hdpi resolution images.
if you only maintain the hdpi, then it is also ok.
android manages all remaining resouces from hdpi resouce directory.
Android application resource directories provide different layout designs for different screen sizes and different drawables. These different drawables are used by android to support a major range of all the android devices present out there. It's a standard practice to put your resources considering these densities. Coming back to your query:
Why android studio can't pick image from other density drawable folder and resize which is possible by eclipse. I can't maintain 5 different drawable folders because there are lots of images.
For your case,In order to maintain this you could create a drawable with nodpi and put your all resources there. nodpi focus resources for all densities.Your resources should be density-independent resources. The system does not scale resources tagged with this qualifier, regardless of the current screen's density.
Hope this will clear your doubts, for more insight you can also look this.
you don't need to add all images to each difference size folder but depending the size of the image you might need to add images to different folders.
simple example is this can occour once you add high res/size images in normal drawble folder
Skipped 100 frames! The application may be doing too much work on its main thread.
This might not crash your app but will make it's performance down.
and
Different density folders were added later on for Android which means that...
If you wanted to be lazy and just add one asset the best choice would probably be the HDPI asset if your min app target < 8 and XHDPI if its >= 8. This is because the system will scale the resource up and down, but you would still want to start off with the highest resolution possible.
If you want to have complete control over how the assets are scaled then you can by all means provide your own for all / some of the densitys. In practise I generally provide HDPI / XHDPI as above and give all the resource buckets for things like logos / AB icons / App icons etc. I generally find the auto scaling to be pretty good and work for most situations, but will occasionally have to supply and extra LD/MD asset if its a small asset / contains small text etc. Plus if i duplicated all assets for things like XXXHDPI I would get pretty good apk bloat.
You can also use IDEs built in tools to add a single asset for many densitys at once. In Android Studio 0.6 this is File->New->Image Asset and a wizard will appear.
I have never noticed or heard of any perfomance impact of allowing Android to scale assets automatically - presumably this is done in hardware.
It may not look great when auto scaling down to LDPI say so you can optionally provide your own scaled assets for all other densities.
taken from : https://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources
Do we need to add all images with different dpi to Android Apps
Is it possible to get an image from res/drawable-xxxdpi if I use a ldpi device?
That is, R.drawable.sunmsg gives me the image link to current dpi.
I do not want to dublicate the resources from res/drawable-xxxdpi to res/drawable
Android prefers scaling down larger sized images than scaling up lower resolution images (quality is given more priority than size/performance).
So if you're using an mdpi device, and you've let's say an image in drawable-ldpi and drawable-xxxhdpi, the xxxhdpi will be preferred over ldpi, i.e. it'll first search for the image starting from mdpi to xxxhdpi, until it finds the image. If not found, it'll start going to lower resolutions and as a last resort visit the drawable folder.
So in your case, you basically don't need to do anything else. Just keep the image in drawable-xxxhdpi folder and let android handle the rest.
But this is not advisable, because scaling down the higher density image is equivalent to decoding a higher resolution image and then scaling it down, so it's going to be performance intensive, defeating the very purpose behind Android provisioning alternative configuration dependent resources.
Check Size and density specific resources
For a detailed documentation, check android's How Android Finds the Best-matching Resource
I have a open source project I have Hosted in github here.
.
Just run that project and that will tell you the device properties
of the device and form a proper folder structure targeting a
particular device
For Example I have a below folder structure for below device
properties.
With those structure you can target a particular device.
There are multiple combinations you can make setting up your
resource folder structure. - check here in android developers site
Check this link too.
.
drawable-sw360dp-normal-hdpi
Hope that helps !!
I was checking my bug reports and from time to time we get this bug report from our app.
I can't pint point what is the actual problem.
This resource does exist, most of devices work fine but some specific devices like LG-E510 or U8815 just cant load this resource.
Any ideas?
android.content.res.Resources$NotFoundException: File res/drawable-xhdpi/action_bar_search_icon.png from drawable resource ID #0x7f02007f
at android.content.res.Resources.loadDrawable(Resources.java:1714)
at android.content.res.Resources.getDrawable(Resources.java:581)
at com.actionbarsherlock.internal.view.menu.MenuItemImpl.getIcon(MenuItemImpl.java:384)
at com.actionbarsherlock.internal.view.menu.ActionMenuItemView.initialize(ActionMenuItemView.java:128)
at com.actionbarsherlock.internal.view.menu.ActionMenuPresenter.bindItemView(ActionMenuPresenter.java:192)
at com.actionbarsherlock.internal.view.menu.BaseMenuPresenter.getItemView(BaseMenuPresenter.java:176)
at com.actionbarsherlock.internal.view.menu.ActionMenuPresenter.getItemView(ActionMenuPresenter.java:178)
As you have stated, if the phone / tab accesses the xhdpi directory then we expect it to scale the image appropriately to fit the screen. Therefore we expect that if the resource exists in ANY ONE of the directories then we will never see a ResourceNotFound exception. HOWEVER:
xhdpi was only introduced in Android SDK 8, so if you target SDK 7 and earlier you may run into problems:
Only use XHDPI drawables in Android app?
Another reason why Android may not be able to access the xhdpi directory is if the device is running in screen compatability mode:
Android - Extra large images placed in res/drawable-xhdpi aren't showing on tablet emulator, why?
Another possible reason is if your drawable is very small and one of its dimensions is rounded to zero as a result of scaling:
Android resource not found because of width and height
Finally, it is possible that some OEM versions of Android may implement this in a non-standard way (e.g "enhancing performance" by not searching the xhdpi directory if their device is hdpi):
Android Drawable hdpi xhdpi mdpi ldpi concept
You should keep your drawables in the hdpi folder. Since the phones that it doesn't work on have less pixels, they can't show the image. Just relocate the files.
Edit: They have less pixels because they have a smaller screen size.