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
Related
I implemented a RecyclerView in one of my Activities.
I use a customized RecyclerView adapter to load data from a SQLite Database (using Room and LiveData-structure) and display it in the view.
All of the rows have a large ImageView where I want to show a Drawable (just a .png). To do that I first tried to use the approach written on the official Android Developers site but it did not work well for me.
Therefore I am trying to use Glide as a library recommended by Google.
I have 16 drawables in my project. They all have a scaling between 800x800 and 1920x1080 pixels.
In my adapter I load the data from my database and based on the drawable id, the image as well (so there is no image data stored in the database; I did this previously).
Unfortunately my App cannot handle that amount of image cache which leads to an OutOfMemoryError exception. That's why I used
android:largeHeap = "true"
in my Android Manifest.
I know this is not a good solution and I also know that there has to be a way to use less memory for such a small amount of pictures.
In Glide I use
GlideApp
.load(R.drawable.my_drawable)
.fitcenter()
.into(myImageView);
But unfortunately the image does not get shrinked or smaller. I thought that Glide can scale the image based on the size of the ImageView, screen size and so on.
What am I doing wrong? Is there a better way to use less memory without fixed scaling so that my pictures not become ugly?
EDIT:
I first stored my images in the basic "drawable" folder in my project structure (copy and paste).
My second approach was the gimp-android-xdpi addon which exports images or icons for any android density (mdpi, hdpi, xhdpi etc.). But this did not help either.
call override(horizontalSize, verticalSize).
This will resize the image before displaying it in the ImageView.
So my app needs to have a maximum of 50 images on the screen at the same time in a FrameView, they need to be placed on top of a base image. If I put these images into drawable, the app crashes after a few images are placed with an OutOfMemoryError. But it works when I put the images in mipmap for some reason without crashing. So I placed them all into the mipmap folders. The images are VERY small too, the largest among them is 2.2 KB and the smallest is 398 bytes. The app works as intended, but performance is horrible after you place a few images onto the screen. The first few images will load quickly, but as you continue to place images onto the screen it gets progressively slower to the point where it may take multiple seconds to place the image onto the screen. I'm just using an ArrayList to put all the Drawables in, and then another ArrayList to put all the ImageViews and I load them into the view within my onTouchListener. Here's an idea. The index is used to decide which image is to be inserted:
drawableOverlays.set(index, getResources().getDrawable(R.mipmap.exampleImage, null));
imageOverlays.get(index).setImageDrawable(drawableOverlays.get(index));
frame.addView(imageOverlays.get(index));
I've also tried using Glide and Picasso and those loaded in even slower. Am I approaching this wrong? Is there a more efficient way to accomplish this?
The best way is create a RecyclerView with ImageViews as items, and then load the images with Glide or Picasso, any of those libraries will give you the best performance
Given:
A number of images (10 - 15) residing in assets folder (as practice shows, the better approach is to keep high-resolution images in assets)
Android UI thread (caching drawables in advance is already made in a background thread)
The issue:
Need to display all the images one on another smoothly and not blocking UI thread after the images are drawn.
Already used approaches:
Dynamically create a required number of ImageView and then call .setImageDrawable(). This takes a lot of time but the worst thing is that the UI thread is being blocked even after all the images are drawn on their ImageView.
Create a LayerDrawable object and pass as argument an array of the required Drawables. Then put it on an ImageView also by calling .setImageDrawable(). This option behaves the same like the one described above.
Is there a way to solve this issue? Or Android devices not capable to cope with it?
Try Picasso library:
http://square.github.io/picasso/
It has support for resources:
Picasso.with(context).load(R.drawable.landing_screen).into(imageView1);
Picasso.with(context).load("file:///android_asset/DvpvklR.png").into(imageView2);
Picasso.with(context).load(new File(...)).into(imageView3);
If you are requiring a smooth transition between images, please try viewFlipper
https://developer.android.com/reference/android/widget/ViewFlipper.html
Basically you can add imageView inside the viewflipper and start animation to move from previous to next image. I am not sure if you need user interactions like scrolling or not. You can try viewPager if user need to scroll betweens images.
Please note that Glide does provide some transition effects for switching between placeholder and image to display. But transition between images are not included, you can have a look here
http://bumptech.github.io/glide/doc/transitions.html
I hope this helps because i am not sured that if you are asking the transition between images or rendering images.
High/medium resolution photo takes time to load from drawable and affects application performance, whereas low resolution photo looks blurred; I want to use high resolution images but not compromise with the performance, How to do that?
I am trying to set a high resolution background image of layout login from drawable, so when switching between components of the same activity lagging occurs.
For instance: switching between field email to password, keyboard appears/disappear in slow motion.
If I were you , I would use the Glide library. Its faster than Picasso and ideal when you want to load large images.
From the github documentation :
Glide's primary focus is on making scrolling any kind of a list of images as smooth and fast as possible, but Glide is also effective for almost any case where you need to fetch, resize, and display a remote image
Yes, use Piccaso. It will adjust and load a correct image size depending on your device and size of imageview.
Hard to know what you need, but you can use a FrameLayout to download multiple pictures in the background and set them invisible till you need it with android:visibility attribute.This solution is for one activity. Asynchronous work and cache can be the answer.
You should consider resize your pic anyway, users prefer see the pic than wait and quit, they know the limitations of their devices (so does 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.