I am using some png images for the backgrounds of activities in my application. These png files are mostly very small sized images. For example, I am using one with the size of 768x1024 which is actually 29.6KB on disk. When I run the application on my Samsung Note 1, I realized that the image actually consumes approx. 3MB of memory. So, Android seems to decompress the PNG file into a full ARGB bitmap (768x1024x4 bytes). I thought that this may be the result of the need of Android to resample/resize the image and placed the PNG file into the drawable-nodpi folder but this resulted in the same amount of memory consumption.
So, what should I do in this case, can I prevent this decompression behavior somehow? I have to put many different images for numerous activities in this project, so it seems that at a point this will cause out of memory errors. I am a beginner in Android and I don't know exactly how the system handles image resources, so I may miss something here.
Try adding these 2 lines to the in to the application tag in the manifest
android:hardwareAccelerated="false"
android:largeHeap="true"
But these are not recommended if you are building a memory efficient App,
But this really works.
Related
In my app, I am going to have 750 PNG images in my drawable folder. I am getting these images by taking screenshots from my computer.
When I built my app with all of the images, the app's file size was 140MB. Then, When I removed all of the images and rebuilt it, it went down to 2.75 MB.
Is there any way to reduce the amount of memory the PNG images take up? Would reducing the size of my screenshot be an effective solution?
I am going to have 750 PNG images in my drawable folder
Most likely, that is not what you want. res/drawable/ is a synonym for res/drawable-mdpi/. Your image will be resampled to match the density of the device, potentially taking up a lot more heap space. Usually, something like screenshots go in res/drawable-nodpi/, to indicate that the images should not be resampled based on density.
When I built my app with all of the images, the app's memory was 140MB. Then, When I removed all of the images and rebuilt it, it went down to 2.75 MB.
I am going to interpret this as meaning the size of the APK, which in turn controls the starting amount of disk space associated with your app. Please understand that Android does not have an "Application Manager", even though your specific device might have such an app.
Is there any way to reduce the amount of memory the PNG images take up? Would reducing the size of my screenshot be an effective solution?
If by "size" you mean "resolution", then that will reduce the file sizes of the PNG files and should reduce the file size of your APK.
As a now-deleted answer points out, you can also reduce the file size of the PNG files using tools like pngquant, that optimize the PNG in ways that your screenshot tool perhaps did not.
And, you can reduce the size of your APK by reducing the number of screenshots. How many of your users are really going to look at 750 screenshots? You might consider packaging a subset of those with the app, downloading additional ones as needed from some server.
If I create a blank new project and run it, it uses 23MB of memory.
If I add one 540x960 png image to the background of the layout, it uses 47MB of memory.
If I add an image button with a background image on it, it uses 64MB of memory.
This continues to go on if I add things, and this is way too much. On the app I am currently working on, I have memory used at between 180-210MB of memory. I figured there was something wrong I was doing with loading the images, so I ended up putting them all on imgur, and loading them in with Glide. This reduced the memory by a small amount, and also doesn't explain why a new blank project would use 23MB.
I thought there might be some kind of setting, but I re-installed with default settings and am still getting the problem.
I experienced a similar issue when I put the drawable in the wrong resolution folder, especially the standard "drawable" folder is a pitfall since it is assumed to contain the image in "mdpi" resolution, so the image gets upscaled like crazy on xxhdpi devices.
Here's a simple test to figure it out, move the images into a folder called "drawable-nodpi" and check for the memory consumption.
Then make sure to provide the image in the right resolution in their dedicated folders, and avoid the "drawable" folder for images, just use it for xml drawables.
What basically happens is if you put your "540x960" image in to the standard drawable folder, it is assumed to be mdpi, if you view it on a relatively modern "xxhdpi" devices the image gets upscaled by a factor of 3 e.g it will be "1620x2880" and therefore consume much more memory.
http://developer.android.com/guide/practices/screens_support.html
hi i am new to android and i have come across some memory management issues whilst using xml to position and design my activity layouts.
most images are around 100kb but vary in size e.g. image 1 will be 512x512, image 2 will be 120x320 etc.
at the moment the images are slowing down my app's performance and sometimes crashing.
Is there a way to reduce the amount of memory an image takes up on an app?
There's a number of steps that applications must go through in order to handle bitmaps sanely.
Small Compressed Size. It's important to balance quality vs. file size for your on-disk (or on-wire) formats. Being able to run PNG files through a lossy pre-processor, or choosing to use WEBP/JPG where needed are critical for each image in your app. Smaller PNG Files covers this more. The problem here, however, is that this doesn't help you with in memory size. Remember when your images are loaded from disk, they are decompressed into 32 bits-per-pixel in memory (in other words, no compression).
Compressed In Memory Format. Android provides the alternate 565 format, which uses only 16 bits per pixel, instead of the 32 bits for the 8888 format. If you're using an image that doesn't need alpha, you should consider the process discussed in Smaller Pixel Formats to leverage loading a bitmap as a 565.
Re-Using bitmap space. Most applicaitons that use thumbnails, only really have 10-20 of them visible on screen at one time (even though there may be thousands to load). The trick here is described in Re-using bitmaps. Basically, once a thumbnail is no longer needed, you can re-use it's space for an incoming thumbnail, rather than allocating a brand new one.
Display resolution. It makes no sense to load a 2MB image, to only display it as a thumbnail. Instead, you should be scaling the image to the resolution of what it'll display at, on the device. I discuss the most efficient way to load these images in the other SO post.
In general, Libraries like Picasso and Glide do a good job at providing APIs that make all this easier; but they are still going through these same processes under the hood.
You have 3 solutions you can do:
1st Solution:
Add in your AppManifest.xml in your application tag:
android:largeHeap="true"
This will try to prevent your app from causing OutOfMemoryError, but use it with caution.
Documentation: Whether your application's processes should be created with a large Dalvik heap. This applies to all processes created for the application. It only applies to the first application loaded into a process; if you're using a shared user ID to allow multiple applications to use a process, they all must use this option consistently or they will have unpredictable results.
Most apps should not need this and should instead focus on reducing their overall memory usage for improved performance. Enabling this also does not guarantee a fixed increase in available memory, because some devices are constrained by their total available memory.
2nd Solution:
If your images' file size are large, you can minimize them by using this online tool: http://compresspng.com/
3rd Solution:
You can use BitmapFactory for loading your images. Here is the Android Developers documentation: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
Hi my Android application is working fine on my Lenovo a319 device , in this device it consuming 40 MB of RAM meanwhile on the Galaxy s5 Device , it consuming 300 Mb for the same build(apk). And I am getting lot of errors such as memory issue on Galaxy s5 device.
For Instance
Out of memory
exception and
android.view.InflateException: Binary XML file line
errors. I have found this Question where it is answered that high pixel resolution will cause memory exception , I am not able to get any clue from that answers provided in that Question , kindly provide the support on the same?
EDIT:
Thanks for the answers but they are inacurate i reuse recycle bitmaps and i make them null, even call system.gc(); and my memory is constant, i just do not understand that why it takes 300 MB of ram at sumasung galxy s5 and just 40 on my lenovo. My lenovo is hdpi s5 is xxhdpi if i am sure.
Looks like your app was built using layouts defined in xml files. These layouts uses images like images for background or source images for ImageButton or ImageView etc. All your drawables are usually stored in drawable-DENSITY folders. So you need to lower resolution of all of your drawables to save some RAM. Like if you have some drawable for ImageView lets call it new_image.jpg and its in drawable-hdpi and its resolution is 800x600 px try to resize it to 400x300 px (you could use a Farstone Image Viewer for this). Do that with every drawable in project and see what happens.
Also it could be that you are displaying images in ListViews using some ImageLoader like Glide (recommended) or UIL or Picasso or whatever use use. Such loaders are usually consuming a lot of RAM (which is configurable however) for caching needs and due to that at one point AOS fails to load, build and represent some your layout which uses images by itself.
Also I recommend you to lern how to display Bitmaps efficiently you MUST know such things.
This thing can be an easy fix for this
just add this line in your application tag in manifest file
android:largeHeap="true"
like this
<application
android:largeHeap="true"
android:allowBackup="true"
......
and if you want to more optimize your code then use Memory Analyser in eclipse
Apart from bitmaps and drawables the most common problem is leaking memory through the Activity context. Make sure that you are not passing around the activity to callback listeners.
A good tool to analyze memory is MAT(Memory Analyzer Tool). It helps you find out memory leaks in your app
I am developing an app which has a lot of images to work on due to which the size of my app has become very large. I want to compress or something like that to reduce the size of app. Any idea?
.png-files which are placed in the res/drawable are automatically optimized when compiling your app:
Bitmap files may be automatically optimized with lossless image
compression by the aapt tool during the build process. For example, a
true-color PNG that does not require more than 256 colors may be
converted to an 8-bit PNG with a color palette. This will result in an
image of equal quality but which requires less memory. So be aware
that the image binaries placed in this directory can change during the
build. If you plan on reading an image as a bit stream in order to
convert it to a bitmap, put your images in the res/raw/ folder
instead, where they will not be optimized.
That being said, you have some more options to try. There is a good talk on this topic from Google I/O 2016 called "Image Compression for Android Developers", which outlines the possibilities, explains their up and downsides and gives some general best practices.
If the size of your application is to high to be published on the market, you'll can either
ship your app without the images and load them from the internet to the phones SD-card when the app is first started
Use Androids own APK Extension Files, which is basically the same but you don't have to do everything yourself.
Use pngquant or posterizer to reduce size of PNG images (these tools are lossy, but give significant savings).
You can also optimize them with PNGOUT, which is one of the best lossless optimizers.
I've written Mac GUI for those.
Always use PNG (.png) images.
And compress it online by uploading your images to
https://tinypng.com/
Simple and sober, always work. You are welcome. :)
There is also a better way to use AndEngine, it saves you from making layout for each phone. And there is no need to use different images for different dpi phones.
Do you use 9-patches for backgrounds? Also you can use imagemagick or anything similar to compress a batch or images.
Try and use ".png".
Use 9-patch images for backgrounds.
If you have title bars, headers with vertical gradients, always use 1-pixel width gradient images. This is a super saver.
If you manage to get hold of Photoshop, they have the option to save images for web/mobile devices. Helps in making really small sized images with good quality.
If u r supporting multiple devices, maintain different versions of the images only for those that are really necessary.