loading large bitmaps at startup - android

I have an intro screen based on this sample but instead of setting colors for background I set an image for each one (I have 3 screens). I have created a drawable folder for each screen density (hdpi etc) and each picture so that I can support multiple sizes and resolutions. Is there anything else I can do or should I do minimize the loading time even more ? Intellij is throwing Skipped 56 frames! The application may be doing too much work on its main thread., however, the application is responsive. I was looking at official performance guide but I don't know if it's an overkill to implement it, is placing image assets into various drawable folders enough for this case ? Or should I do those calculations on top of it ? here is what I do now:
<ImageView
android:id="#+id/welcome_image_view"
android:layout_width="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:srcCompat="#drawable/love"
android:scaleType="centerCrop"
tools:ignore="ContentDescription"
android:layout_height="0dp"
app:layout_constraintRight_toRightOf="parent" />

I would guess it's the code you're using to load the images more than your layout file that's causing the frame skipping.
You really have 2 goals. 1st, minimize actual loading time. Users don't want to start at empty screens or place holders more than they have to. 2nd, move the work off of the UI thread. Any image loading but the smallest of images shouldn't be done on the UI thread.
For 1, make sure your images aren't any larger than they need to be for display on a device.
For 2, the doc you pointed to recommends Glide. (Most of the rest of that doc probably doesn't apply to your case. Much of it is for when you have a full res image but only need to display a thumbnail or other reduced resolution image). AsyncTask is a common way to do simple work off of the UI thread. (Thread and Runnable are other ways but I won't get into that here).

Related

Two similar images (same res, size, etc) added in ScrollView, one makes it laggy, the other does not at all

I'm putting 10 different images with texts in a ScrollView, vertically. It made the app laggy depending on what images are shown in the device screen. The xml code is like this:
<ScrollView>
<LinearLayout>
<!-- 10 times -->
<LinearLayout>
<ImageView />
<TextView />
</LinearLayout>
.
.
.
</LinearLayout>
</ScrollView>
So I tried replacing all 10 images with 1 image resource only, the app became smooth, no lag at all. I tried replacing all 10 images again with another image, this time, it became very laggy again. Then I tried, replacing 9 images with the first (smooth) image and 1 image in the middle with the second (laggy) image, and the app is lagging only when it's showing the second image.
I checked these 2 images' properties though, and found out that they have the same width/height (1280*720 pixels), h/v res (96dpi), bit depth (24) and both at about 40kb only. So I'm wondering why one is so smooth to use, but the other one makes it very laggy. These are the 2 images:
smooth to use pic
very laggy pic
How can that be?
EDIT: I copied all images and pasted it to all drawable folders (xxxhdpi,xxhdpi, etc) and now it's not laggy anymore. Hmm..?
The thing that slows down is to load a large bitmap and then display it in a much smaller space, it is far more efficiency to load it already scaled down.
Here it explains : https://developer.android.com/topic/performance/graphics/load-bitmap.html
It is the well-known system of loading thumbnails instead of the whole image so used when internet speeds were slower than the current ones.
If you are downloading the images from a database it will be more efficient if the two versions of the image, small and large, are previously stored in the database.

Thread assistance

I need some help,
I am creating an app, and want it to run faster I mean when the app is started first it shows a blank white screen for o 1-2 seconds and then loads images. I have a layout background image, and 4 imageviews which are clickable and take you to the next activity. I read somewhere i should use threads to load images and it will load them on a separate thread faster, but i have some problem using it.
So here are the problems and android studio explanations:
Thread thread=new Thread(
public void run(){
ImageView tipka=(ImageView)findViewById(R.id.tipkaproba);
tipka.setImageResource(R.drawable.instructions);
LinearLayout asd=(LinearLayout)findViewById(R.id.layoutproba);
asd.setBackgroundResource(R.drawable.backfround123);
}
).start();
Now the android studio says: 
After
"Thread(" )expected
Before
"public void run(){"
; expected
On ").start();"
Invalid method declaration; return type required, Missing method body, or declare abstract.
Now i would like to know:
Does this speed up loading images, ( if not how to do it then)
How to fix my errors.
Thanks anyway !
Do all images fit in the screen?! If users need to scroll to view other images why load all of them at once? Use a grid view with adapter to load the image. In this way when the app start only images on the screen will be loaded and then when the user scrolls other images show up!
another thing you can do is to have 2 version of each image. one low quality with small size that loads first and one for high quality image. that will load latter. You can also calculate the base color for each image (use open source code or do it manually). then set the background image of iamgeview to this color. So when the image finally loads on the screen. The difference is not as dramatic as it was before.
If you want to use thread try AsyncTask first. Using AsyncTask is simpler than defining thread yourself.
Try to decrease the size of your images! If you be able to do this. it works better than any other trick! It's mobile, you don't have to show supper high quality images. users don't even notice most of the time
You probably took care of this but it worth mentioning that you need to provide different images for different screen densities and it's critical for performance as well as quality.

Android Fragment Background images

i am new to android and i want to set an image as background to different fragments in an activity.But the images are to large that they make my application to increase in memory and i don't want this. The activity have 6 different fragments and each have different background, here i set the background images from drawable.
i referred this.but i didn't get correct solution.
How could i make them so that the memory size of images will be less?
Android - Reduce the memory usage of Bitmap Drawables
On this concrete case you have 2 options:
1 - Set the image as background on the root view of your fragment Layout. Doing that you'll avoid out of emmory errors, but the image will be scalled to fullfill the whole screen, so it could be diformed.
2 - Use Picasso library http://square.github.io/picasso/ to load the file images. It can be helpful to manage memory issues.
Also, the best thing you could do before starting is to reduce the size of the images using some software such as https://tinypng.com/.
Hope it helps

how to clear memory when it is full because of using too many backgrounds in android

Hi guys i am new to android and i posted a question a week ago in this link which basically stated that i was getting a java.lang.outofmemory error when i was using a lot of different backgrounds for my activities.
why am I getting errors when I use different backgrounds in xml
So as a new developer I have searched and searched for a solution as to how to clear the memory as i go from activity but none have been clear or precise. Then i stumbled across this site http://androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/
which described exactly what i was going through except they use 10 activities and i am only using 4. However when i implemented his code it my project i ended up with null pointer exceptions and after fiddling with his code I ended up back were i started with the same out of memory error.
So can anybody direct me to someone who can show me how to have as many backgrounds as i want with out running out of memory. Or does android as great as it is does not let you simply use more than a certain amount of backgrounds? help?
It's not that there is a limit on the amount of backgrounds, but each background image you load is a loaded into memory as a bitmap and held there until the activity is destroyed. If you are opening multiple activities one after another, each background image will need to be held in memory and so eventually you will get an out of memory exception.
If you set a large background image, you will also experience some blocking on the ui thread, while the image is loaded into memory.
One way around this that worked for me was to use an imageloader. This decodes the image off the ui thread, caches it on disk, loads it into memory and if memory is running low, will clear an image from memory and fallback to the disk cache. You may get a slight delay/fade in as the image is loaded but this is not so bad visually, and when loaded once, will load straight away if you go back to that activity.
Check out Picaso Picasso which is really easy to implement and a great api or Universal Image Loader.
My layouts were all RelativeLayouts and the first child (will be behind all other views) was an ImageView with scaleType centercrop and width and height set to match_parent. When each activity loads (onCreate), just grab a reference to the imageview in your layout and set the required background image using your ImageLoader of choice.
The other option is to have multiple copies of your background image in your resources, with each one resized to perfectly fit your resolutions of choice (drawable-mdpi/-hdpi/-xhdpi etc). This way, you ensure you are never loading images that are way bigger than you need to be displayed and your app will be more forgiving in terms of memory consumption.

android out of memory for including some image buttons

Actually I have for so long wish to know how to present graphics in a proper way.
In an activity, I have the following:
a background (png, full screen, 768*1280, 1.36MB)
3 icons (each icon has pressed and not pressed: 2 states, using 1 png 400 * 400, 300KB each), i.e. 3 icon * 2 pic * 300KB = 1.8MB
some more textviews
When the app starts off and directly goes to this activity, everything is ok, the activity can be presented properly.
Yet somehow when the app has run for some other activities, and then goes to this activity through a dialog box, then most of the time errors will occur, as follows:
Out of memory on a 15728656-byte allocation.
Question:
I have researched for sometime and some say to bitmap.recycle(), yet how to implement? through the onCreate? or actually 400*400 is too big?
If I want to change the background of an activity upon users' choice, i.e. when he presses button A, the background changes to bgdA, presses button B will change background to bgdB... in that way how that can be achieved?
Many thanks!
Depending on where your asset is stored is the amount of memory it might take, since scaling factor is calculated between the difference of densities, this is a little gray area because I haven't found any official android documentation that backs this info up, however I've seen that error so many times and this is the way I handle it.
1.- If you don't have the asset in the proper drawable-(density), this will cause problems because depending on the devices you are actually supporting, you should put the asset in drawable-xxhdpi or drawable-xhdpi, you will notice how the memory will decrease considerably
2.- If you don't want to mess with densities because it's a generic image which don't have much details(like a simple background), then add the asset in the drawable-nodpi folder, it will prevent android from trying to scale the asset it self..
3.- As good practice, try to create the asset with the proper size for the proper densities, 400 x 400 seems like too much for an icon, this will also prevent you from OOM, not only in this activity, but for other activities that might also need to load a good amount of assets, giving scalability to your app..
Always take on count that leaving the "resize" of an Image to the OS might cause huge amounts of memory allocated because the OS will try to resize it based on the formula width * height * 4bytes, the 4 byes are for ARGB of each pixel, 1 byte per color or alpha, so if your image is for example 1090 * 1920, it could easily become internally 8.3MBs even tho the actual image size is only a few KBs, and if it tries to scale it, it might double it's size too.
Hope this Helps
Regards!
Make sure you have a copy of your image for every drawable folder in you res, for example if you runnig your app on the S4 phone and you don't have all the images in the drawable-xxhdpi folder you will run out of memory even with reasonably small images.
Also if you need to change background at run time use setBackgroundResource.
Hope it helps
This is the common problem in android here is the proper solution
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
In easy words you have to scale the image down according to your requirement

Categories

Resources