I'm building an application with very big sized images.
Almost all of my UI components are made of ImageViews.
I only have to show 12 images(ui components) on my first activity, but it consumes 80mb on startup.
The images are divided into each drawable directories using Android Drawable Importer.
By doing this I was able to reduce the runtime memory(which I can see on the Android studio's device monitor) to half, but it is still consuming 80~120mb of memories, which I believe is too much.
The first question is, isn't 80~120mb too much for a four screen(two activities, three fragments) application?
The second is, if it's too much then, what and how can I do to reduce memory usage?
When working with images keep in mind that there is a HUGE difference between compressed format (jpg, png..) and Bitmap. Computing the size of a Bitmap is pretty easy, it's width * height * 4 bytes (assuming that the bitmap has the default configuration argb888). So a full hd image that compressed is xy kb, when decompressed will occupy 8294400 bytes (~8mb). So my advice to reduce memory consumption is... scale down your images. You're asking if 80-120 mb is too much, well it seems like a lot but it really depends on what you're doing. What happen if you force garbage collection (there should be an icon in the device monitor)?Another thing to take into account is how to decompress the images, refer to this and use a library (Picasso, Glide..).
Related
Apologies in advance for such a basic question, but this is my first app and I can't quite find a clear answer for my situation. All the images in my app are stored in the drawable folder, I'm NOT downloading any images from the internet. All the information I come across when it comes to multiple image sizes seems to refer to the occasion when the app is fetching images from the internet.
So currently most the images in my app are one size, customized for the largest size - xxxhdpi. However, I understand the app is doing some work to "shrink down" those images for the xxhdpi size screens.
I'm having second thoughts about this one size fits all approach. I'm thinking that perhaps the app doing the work to shrink the image down might take up extra memory and negatively impact performance. I've been looking at the Android Studio Profiler and I've been trying to understand the Graphics Process when I look at the Memory Graph.
More generally speaking, is there a benefit to having the smallest size images possible, even for the xxxhdpi? For example, does it hurt (memory wise or in some other aspect) to use a .png image when I could use a lower quality jpg? Again, just to super clear, this is just in the scenario when the app has all of its images in the drawable folder. My app has options where players can change the game background and other images so I want to be sure I'm optimizing how the images for best performance. Thanks.
Memory. If you load a bitmap of x by y pixels, in memory that takes 4*x*y bytes. For a full screen image, you can expext that to be 4000*1000*4 or 16 MB. That's a good chunk of memory to a small device, which also tends to have less RAM. If instead it needed one at half the resolution, you would have 2000*500*4, or 4 MB.
Obviously this scales with size. The smaller your images, the less memory wasted. I wouldn't argue that you need to provide every size, but if you're using large images I'd provide more than one. Also, for anything that isn't incredibly complex (like icons) I'd consider vector images instead (although that's a CPU time vs memory tradeoff).
You mentioned png vs jpg. There's two things to consider there: apk size and image quality. JPG is smaller, so it will lead to a smaller apk size. PNG is lossless, so it will have higher quality (although whether that matters requires a human visual check- it matters less than you'd think on a lot of things). Interestingly it doesn't effect the amount of memory used at runtime, because both are held in the Bitmap object uncompressed.
I am developing a small tamagotchi for a school project and I have huge problems with the amount of memory the app is using. At first I had 200MB allocated to the app and after a bit of researching I got a easy fix to reduce it to 50MB by renaming the drawable folder into drawable-nodpi. But this is still way to much. While investigating the problem I'm sure that it has something to do with my Layout and UI-Elements because i deleted all my Code and launched my app only with the Layout and the memory usage didn't drop at all.
Here you can see my Layout:
The image-sizes are in average about 30kb and if I calculate the maximum size of possible images in the memory I have around 1.5MB.
So where does all the memory come from? How is that even possible?
If you want to see the app by yourself you can get the project from github:
https://github.com/kruben95/TamaStudent
I would be happy if someone can help me or give me some tips.
I downloaded your project, and here is some suggestions:
1) images are big resolution even if on disk they take 30-40 kb - in memory they are bitmap and bitmap takes a lot of memory, for example body part - 1200x1980 pixels with 4 bytes per pixel this is 9,5 megabytes in memory!!?? now after this bitmap got it must also scale it - this is additional memory, and as you see you have more then 10 megabytes per only one image!! this is extremely HIGH.
2) make images lower resolution. no need to display them so high res.
3) remove from images invisible parts - as i see very big parts are clear
but it takes memory!
4) try to make some images programmatically, like circles etc.
5) in code - don't use alpha for view if you only need to do background, set this alpha directly in color: #00FFFFFF - here is white color with alpha 0. If u use alpha on view it will take additional memory for redrawing (lower performance).
6) google internet for your related topics with tag Best practices and you will find a lot of useful information )
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
Why do we have to provide images for all screen sizes when developing mobile applications? Wouldn't it be more efficient to just have 1 very large image for each unique image and then scale the image down whenever the app is being run on a smaller device? It would definitely make the game's file size much smaller.
In lots of cases, it wouldn't look as good.
If you find a set of well designed icons, you'll see that they've been independently designed for each resolution: the smaller ones will deliberately have less detail in, because downscaling just doesn't produce as good results.
Here are two GNOME icons, for the same thing, but one at 256x256 and one at 48x48. You can see that the 48x48 one has less detail in the writing on the letter, but the writing is also designed rather differently: on the 256x256 one it looks like the middle page of a document, and on the 48x48 one it looks like the opening of a letter, with an address at the top.
It would make the size of the .apk file significantly smaller, but it would have more undesirable tradeoffs for runtime efficiency.
Having to load large bitmap objects and scale them down is an un-necessary load for the device's processor. But more importantly, having to load large bitmap objects into memory makes the VM's memory fill up more quickly. This means that the VM has to do garbage collection more often, which can cause noticeable delays at runtime (this can cause animations to lose frames and look rougher).
I am developing an android application. I have a custom view which is a functional circular progress bar. It has 12 circles uniformly distributed over a bigger circle.
Since the design is simple and geometric I can achieve the desired results by having a one small circle and rotate it around the center. That will cost me one file on disk, one bitmap on memory - which is kinda small, around 300kb on memory- and some amount of cpu power on rotating and drawing the bitmap.
Another option come to my mind is that I can have all 12 images ready on disk, load all of them on memory, and draw the appropriate one each time. This option doesn't have rotating overhead.
Now my question is, which one is more viable/reliable in general, and specifically for android. You can assume 10 fps is more than enough. And if you think it wont make a noticeable difference please let me know.
I'd rather have 1 image and rotate it at runtime. That isn't too costly an operation, and loading N bitmaps into memory can take up a bit of memory, which apps are already hurting for.
In general. I prefer having minimizing my resources as much as possible. Rotating a small bitmap like that won't cost too much power and packaging 12 of those (12*300kb) is a considerable increase in app size. However, you have to consider this in relation to your overall app size and requirements. If you need to minimize size, rotate it and if not, load them all into your app.