ScaleDrawable has its own constant state? - android

I've seen the blogpost about how android handles drawables and how to save memory using mutations, creating different constant states.
Lets say I have a bitmap pic1.jpg which I use it in some part of my app and I have a ScaleDrawable that scales down the resource pic1.jpg.
Q1: Will they share the same constant state?
Q2: Will android load 2 images in memory (pic1 and the scaled version of it) or just pic1 ?
Q3: Is this better, regarding loading performance and memory consumption, than having 2 resources with different sizes?
Update:
ScaleDrawable doesn't seem to be working, at least I've tried it out and the drawable is not shown.

Related

Vector Drawables vs Bitmap in terms of RAM (Android)

In terms of RAM utilized by a drawable when it is rendered on on the screen, does it make any difference if the drawable is a vector or a bitmap?
I understand that vectors take less media storage space, but I'm asking about the resident RAM needed in order to render it, since in theory, it is still being drawn onto a canvas with the same amount of pixels in the end.
Thanks!
From the document I read sometime ago (same question with you).
The different between these 2 options is the size of APK file after all when you release. SVG will help you save size of apk.
The initial loading of a vector graphic can cost more CPU cycles than the corresponding raster image. Afterward, memory use and performance are similar between the two. We recommend that you limit a vector image to a maximum of 200 x 200 dp; otherwise, it can take too long to draw.
Being drawn on view will have those 2 options having same RAM (memory) consumed.
My reference source: https://developer.android.com/studio/write/vector-asset-studio.html#about
use vector drawables for simple shapes. Using the same for complex structures will increase the size of the apk rapidly.

When to use VectorDrawable?

Android Lollipop has introduced several new classes, one of them being VectorDrawable. I was just wondering when will it be suitable to use VectorDrawable over a bitmap image knowing VectorDrawable has a performance drawback. The only thing with VectorDrawable is scalability which comes at the cost of performance. So when is it that I can use a VectorDrawable if performance is the priority? Is the performance drop too high?
I think the "performance drop", if present, would be acceptable. One would hope you are not creating a ton of vector drawables every frame. Presumably, you would load the VD once, cast it into a drawable at which point the vector drawable isn't needed anymore.
Really the only thing that I can see that would cause an issue, is if you are loading an absurd amount of them all at once. But why would you? At that point, just something like a presized sprite sheet.
Note that VectorDrawable (comparing with BitmapDrawable), only has the initial drawing performance overhead. After the 1st frame the VectorDrawable show up, the framework will have a bitmap cache. From that on, all the performance of that VectorDrawable should be the same as the BitmapDrawable, as long as the size didn't change.
VectorDrawable is not recommended for huge background image, like full screen size, but for buttons and icons whose size is normally smaller than something like 200dp x 200dp. You should be able to use it without worrying too much about the performance.

Android ImageView.setImage* vs. BitmapFactory.decode*

I'm currently facing several performance issues (out-of-memory) when handling a vast amount of bitmaps. As this is just a problem that can be fixed I'm wondering if anybody can explain me the difference in using the following methods.
If I only want to load an image into an ImageView I usually use:
imageView.setImageDrawable(getResources.getDrawable(R.drawable.id));
If I want to sample the drawable beforehand I usually use (here without sampling):
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.id);
imageView.setImageBitmap(bm);
My question is related to performance optimisation. I'm wondering whether it is better to provide as many drawables as possible using the different drawable folders (so these drawables nearly fit the required resolution for the different devices) or if it is better to sample high-quality drawables? What is setImageDrawable doing internally? Does it decode the resources using the BitmapFactory, just without sampling? There seems to be a trade-off between the actual size of the app and the cpu- and memory-load during runtime.
if you're concerned about apk size, then having as many drawables as possible is not the ideal way to go. but dont forget, when you decode a bitmap, you can pass a sample size so it will scale down to the screen size and only give you the pixels you need, so older phones with smaller screens wont need to decode 8mp images.
check BitmapFactory.Options and here

Using vector images to scale for app platforms

Images in apps come in many shapes or sizes, but to save space and editing time is there a way to use scaleable vector images?
Ideally I would have one vector image at middle resolution, I could then detect the screen size and scale the vector how I need and add the background using some custom gradients.
I'm using titanium for this.
Titanium doesn't yet support vector graphics, though it is available in native Android code via Shape Drawables. There is a third-party SVG library available for Android SDK.
For Titanium, branch the code based on the device screen size (Titanium.Platform.DisplayCaps), and find an image that works with decent performance on the device.
You can use PNGs with transparency and apply a background color to your view object.
I've found away round making different sized drawable:
Basically just one have folder called drawable within the res folder.
Make your artwork in what ever you use but make it large (at least 1080p for future devices).
Save the image's as PNG within the drawable folder but save them large. (IE at least 1000x1000)
Write a function that loads in the PNG but scales it (according to screen size & percentage of what size you want the drawable to be. So 20% of 800px width is 120px). I've managed to do this bit with 30ish lines of code, can't paste my code since I'm not on my working machine.
For me this has worked across all my apps for all devices, I've not had a single crash yet (1000's of installs, including Live Wallpapers).

How does color depth and/or compression level of images affect UI performance?

To what extend do color depth and compression level of the original jpg and/or png images used as drawables have an effect on the app's UI performance, given the fact that all images are converted to bitmaps internally anyway.
Especially considering i.e. images in list views for example.
Same question goes for png vs. xml shapes as drawables.
Edit: I found a similar question which addresses memory usage, but my focus is more on UI performance (i.e. scrolling long list views, etc.).
Is decreasing size of .png files have some effect to resulted Bitmap in memory
Larger images probably take longer for decompressing, but when they're cached properly (and i.e. asynchronous lazy loading), after initial loading, it shouldn't matter anymore.
If the images are indeed all are converted to bitmaps internally anyway, then I think you're right, the compression level of the original file makes no difference once the image is loaded.
Color depth of the image, on the other hand, would still be a preserved difference, right? I.e. image files of different color depth on disk can be loaded to in-memory images of different color depth. So I would expect "deeper" images to have an adverse effect on performance eventually.
But as always, you never know for sure about performance till you run tests.

Categories

Resources