Dear Folks,
I have idea regarding the general Memory Structure and how the OS manages the memory by using different mechanism!
I know that android uses linux kernel and there would be memory management module which would control access the way the memory is allocated to a process.
I recently had my doubt arising when i ran through the Out of memory exception in android.
Consider I have 10 images to be displayed in an activity and when my application opens the said activity all the 10 images would be loaded in memory and will be in the primary memory until my app is pushed to the background. This is how I understood so far regarding the processes in any operation system.
But I also ran into the doubt once the images are loaded in the memory and dispatched to the GUI I mean set to the activity , will not those images be present in primary memory or they will be cleared out from the memory ?
Please help me in understanding this!
I already Google -ed it, but not able to find what I needed
Thanks in Advance
This is completely wrong. You should not load 10 full sized images at all. You usually load them way smaller, directly from the disk into Thumbnails that are not a few megabytes each. You should read this article: https://developer.android.com/training/displaying-bitmaps/load-bitmap.html
Related
I have a problem. I created the android app, when I start the app I see 48,09 MB cache memory. My app uses different libraries, has a lot of classes. I can't find a reason why the app uses so many cache memory? How do I find the problem?
Interesting thing: When I start an empty app, this app uses approximately 4Mb cache memory , I think it's too much.
I have a listview and each listview item when clicked opens a gallery (conating 30 + images ) to be downloaded (using the urls).I don't want to re - download the images on next visit and also want the images to be present when i click on list in offline mode.
I went through several links in SO and am a bit confused on which approach to follow:
1> Use bytearray and store the images in sqlite db.
2> use context -> getExternalCacheDir() to store it on the
external memory (this wont work on devices with no external
memory.)
3> Use SoftReferences as suggested in following link
http://android-developers.blogspot.in/2010/07/multithreading-for-performance.html
Please help to guide me on the best approach to handle around 1000 + images which works in offline mode as well.
1000 images.....I sure hope they're thumbnails or you're going to end using a lot of storage space.
You should really only cache what you need and what images are used repeatedly. Both options 1 and 2 are dependant on the phone even having storage space, if there's no space then you won't be caching much to disk. 3 won't store images permanently, if the app is put in the background and gets killed and so will the cache.
It's hard to say what the correct decision here is without knowing the inner workings and requirements of the app.
Just going by what you want then I would say go with several solutions
If there's external storage write to that, if not use internal storage, if there's not enough space internally use the soft references.
I have always found that out of the box caching solutions never fit quite right with my apps and wind up writing my own cache. Sorry I can't give a better answer.
PS. If you're not careful with 3 you might download too much and run into an OutOfMemoryException.
PPS. 3 can also throw a RejectedExecutionException which is caused by too many async tasks being started at once (eg scrolling quickly through a listview that gets an image via asynctask)
I'm using Jake Wharton's DiskLruCache lib.
I'm curious about app performance, caching strategy, using caching both in a view and across a whole application. Most of the time, the image won't change.
Let's say for example I have a 320x320 photo on my server. I open the stream, save the image.
In my list views, I show bitmaps and in the detail, I show a larger image. Should I save a thumbnail bitmap too? Is that more efficient?
What is your experience with sharing the cache "object" across the entire app (let's say I have multiple views that might leverage the same data. What are the issues with this?
For the sake of performance and currency, what if the image changes on the server. What's the best strategy to know that it's changed? I don't have access to modified date. Only size and yet, I don't really want to query size every time either. Set a flag in the app on the server and then query the flag?
In a traditional application (if there is such a thing), what's the best practice for clearing the cache from time to time? (indent weirded out.)
(I was inspired to write this after seeing all of the performance improvements by Facebook in iOS. I don't have billions to do caching but I would like to at least be smart about it! LOL)
A lot of these answers depend on the type of app you're writing, how important image updates are (and how likely images will change, etc), and total images produced. Aside from disk caching, you should be using memory caching as well, especially in ListViews and other areas where the same images will be scrolled through repeatedly. Look at LruCache and read the Caching Bitmaps entry from Google.
320x320 is probably too big for a listview, you will likely want to create thumbnails (depending on device, and how you're implementing your listviews).
1) You should be using Disk caching fairly aggressively (how you define that is up to the app you're writing). Use the external storage directory, and if they have a few GB left over, it's not an issue if you take 100 mb for your app for instance. It can all be cleared away if it's ever needed anyway.
2) There shouldn't be an issue. Disk IO (even to a flash medium) should never be handled on the main thread. Use AsyncTasks to load the images. There can only be one main foreground activity at once anyway, and while an activity is sleeping, it shouldn't be trying to read from the disk anyway.
3) Again this depends on how you're implementing your app. You should be able to get additional information when retrieving the file (even Apache can tell your app the last modified date).
3.1) You can have a sqllite db that keeps track of how often certain images are used, and most recent read. If the most recent read is a few days old, let that image expire.
Edit: There's a library from Jake Wharton now called Picasso that I would recommend using, which handles the Network/local IO as well as memory and disk caching. Check it ou here: http://square.github.io/picasso/ . A lot of what you will need to do can be accomplished with one line: Picasso.with(this).load(imageFileURL).into(imageView);
Can an android app read the memory (the RAM meory) of another app that is running?
Appreciate any pointers.
Do you mean the part of the memory that another app is using for code? Then No.
I assume that someone might find a way, but that would be a security issue, a bug in the system and something that would be adressed in an update. You should stay out of 'other' pieces of RAM.
Or do you mean something like internal memory where you can store a file? An app can save a file in several ways, including some that let other apps read them (example: if you take a picture with a cam-app, you can read it with any gallery app).
We have an Android application that throws out of memory error on Android 1.6. It is working fine on 2.0 onwards. We are trying to cut down on the runtime memory usage at this point.
We were thinking of reusing images – such as the background image of each screen. Is it possible to load the background image once in the memory at the time of app launch and reuse this cached copy in each screen rather than each screen loading the same background image increasing the overall footprint in the RAM?
We understand that there many other ways and best practices around runtime memory usage. But at this point, we just wanted to know whether this “image reuse” approach is really feasible?
If yes, how can we do this? Will it at all save any memory or the Android OS will still create multiple copies of the same asset for each screen not giving any benefit from the memory perspective?
Thank you very much for your time in reading my post.
If that background image is loaded as a Drawable from a Resource, it's bitmap data is already shared between all Drawables created that way. So no, it probably wouldn't benefit you in your particular case.
Yes you can reuse images.
It is usually done for ListViews where each row contains the same image.
In this case, you can get the Bitmap once in the constructor of your adapter, and reuse it in the getView() method, so you don't have to load it for each row. This trick is presented here
In your case, you could load your background bitmap in the onCreate() method of your main activity, save it as a public static attribute and then re-use it in all your activities.
But I think it won't make that much of a difference and surcharge the code for nothing.
As you are working on tweaking your UI, I suggest you watch the 2009 Google I/O Presentation by Romain Guy, if you did not see it yet. It shows a lot of useful tricks for boosting an UI's performances, especially when it comes to Bitmap manipulation.