I have an Android application with which user can share posts with images on the server.
Images are taken by the camera - therefore I change the size to a smaller one and compress it.
I also need the image to be in 2 formats - regular and thumbnail.
I guess better to create 2 versions on the device and U/L both?
I also do it in BG, so user will not be blocked for long time...
Is it a good behaviour?
Should I block the user for 10-20-30 seconds (depending on the network speed?)
What is the common use?
Recommnedations?
No ... it would be a better experience if you just upload the large image, and have the server take care of thumbnail generation. That way, you can minimize the user's data usage, and also the time it takes to upload an image.
Also, definitely don't block the user ... do the upload in the background, and let the user continue using the app.
Sending your images using the multipart content type.
If you have an additional step where the user start typing additional information (like a title, description etc.) you can start uploading your image so that the user won't notice the delay (do it asynchronously). That's what Instagram does.
Speaking of the size of your BitmapI think you should consider sending only one normal version of it and let the thumbnailing be done by the server. However you have to compress it (JPEG/PNG) and you can also scale it down by a factor of 2 otherwise you might experience memory errors.
On a side note (not really related to your question) be careful of how much memory is left for your app to use when displaying a large amount of Bitmap. Before Honeycomb, Bitmapwere allocated on the native heap but accounted on the VM Heap (if I'm not wrong) so don't count simply on how much memory is left on the VM heap. This talk is worth a watch if you haven't yet.
Related
I have been coding this application that shows images of bus lines schedules. There are currently 32 lines and each of them has it's own image (can't use text due to the formatting and lack of data, had to do a compromise). I made it fetch an echo from a PHP file on my server and it retrieves data regarding bus lines and their images, then it downloads that data and images to the internal storage and loads the buttons for each line (dynamic layout).
ImageViews are set to null when they are created and they are only populated once you click on the button. I have noticed that my app uses around 20MB of RAM just as it starts. Opening 10-15 lines (10-15 images are loaded into ImageViews), RAM usage climbs up to 60MB and then it crashes (reaches my device's heap size limit). I know that image intensive applications tend to use a lot of RAM and my plan is to limit it to only one image per time (so once the user clicks on some other bus line, the others are closed and their imageviews are set back to null), but what is wondering me, can empty ImageViews cause RAM to be around 20MBs? My images are 320px in width and ranging from 200 to 1500px in height (I know, it's a lot), but I have set them to grayscale and compressed them (Size of the images is from 50kb up to 150kb).
My application's APK is 710kb in size, app when installed is around 3MB and with data it totals to 7.5MB.
So, to clarify, my questions are:
*1) Can empty ImageViews cause high RAM usage as well?
2) If yes, should I dynamically create an ImageView and populate it once the user clicks on the button, instead of the current approach when they are all created at startup?
3) Can multidimensional variables (mostly strings, 6 strings with 35 dimensions) cause high RAM usage as well? Most of them are around 10 characters long.
4) Are there any tools which I could use on Android Studio which could help me to locate possible memory leaks?
5) Do non-global variables get automatically destroyed once the ie. function has returned a value or do I need to manually set them to null after I'm done with them?
6) What are generally some good practices to reduce RAM usage on Android when developing an app?*
Sorry for not being very technical here, I'm not a professional programmer or anything, this is more of a hobby of mine and I'm trying to learn a bit more here. Thank you for reading.
Image that shows what my app does:
All bus lines are collapsed
Once you click on the button, it shows the bus schedule for that line
*1) Can empty ImageViews cause high RAM usage as well?
Probably not. It's the bitmaps themselves that take a lot of space, not the ImageViews. Keep in mind that in-memory bitmaps won't be compressed, so it's not the file size that you need to take into account but the number of pixels.
3) Can multidimensional variables (mostly strings, 6 strings with 35
dimensions) cause high RAM usage as well? Most of them are around 10
characters long.
Probably not.
4) Are there any tools which I could use on Android Studio which could
help me to locate possible memory leaks?
You should use the Android Debug Monitor (Tools menu > Android > Monitor (DDMS included). It has a memory heap viewer that will show you what the big offenders are. It can take heap dumps in HPROF format that you can also analyze with other Java heap viewing tools.
5) Do non-global variables get automatically destroyed once the ie.
function has returned a value or do I need to manually set them to
null after I'm done with them?
Unless you're doing something strange, the memory used by local variables is eligible for garbage collection once those variables pass out of scope, so to answer your question, you don't need to set them to null.
In my case, I only put the 1 image to drawable so the RAM of application increase a lot.
Then, I put image to each drawable-...pdi files, the RAM size decrease
When I upload an image from a mobile device you have two options:
reduce the size on the device and upload the result
upload the full image and reduce the size on the server
Which one is better?
For the user experience, it is better to do all the work you can server-side, minimising the processing time and the transfer time.
I would recommend doing all the work on image on the server if you want the application to be fast, and if the transformation make the image heavier.
Now you may have problem in the future if you have mutliple upload in the same time with a low performance server. If it is the case, choose to do the work on device to devide the work on each device.
I think The "1" is best,because This way of consuming less flow;this option is very important for android app
I always use the 1st approach. You never know how fast your user's internet is, so I prefer doing it locally and save time on the upload.
That is specially true in 3d world countries where 3G speeds are generally very slow and unreliable.
Guess what, another Android-Bitmap-OOM question!
Background
Whilst stress testing our application it has been noted that it is possible to max-out the app's process memory allocation after sustained, heavy usage (monkey runner like) with OutOfMemory exceptions being recorded within the ensuing stacktrace. The app downloads images (around 3 at a time) when a page under a ViewPager is selected. There can be 280+ images available for download when the length and breath of the app is exercised. The application uses Picasso by Square for it's image downloading abstraction. Notably, at no point in our application's code are we manipulating Bitmaps directly...we trust that the very talented Square Inc. employees are doing it better than we can.
Here is a picture
The below plot shows the heap allocations over time recorded under the dalvikvm-heap log message. The red dots indicates a user bringing a fresh set of articles into the application in order to bolster the amount of work outstanding and stress the app...
DALVIKVM heap allocations http://snag.gy/FgsiN.jpg
Figure 1: Nexus One heap allocations; OOMs occur at 80MB+
Investigation to-date
Against a Nexus S, Nexus 4, Wildfire, HTC Incredible and a myriad of further test devices, anecdotal testing has shown the memory management to be sufficient with the DVM GC 'keeping up' with the heavy lifting work being completed by the app. However, on high end devices such as the Galaxy S II, III, IV and HTC One the OOM are prevalent. In fact given enough work to do, I would imagine all of our devices would eventually exhibit the failure.
The question
There is clearly a relationship between screen density (our requested image sizes are based off the size of the ImageView), the process memory allocation and the number of images at a given size that would result in the app exceeding it's heap limits. I am about to embark on quantifying this relationship but would like the SO community to cast their eyes over this problem and (a) agree or disagree that the relationship is worth making and (b) provide literature indicating how best to draw up this relationship.
It is important to note that if we destroy the image quality our OOM all disappear but alas the UX is poorer which is why we are wanting to be dicing with the most effective use of the available heap.
Side note: Here is the portion of code responsible for loading these images into the views that have been laid out;
picassoInstance.load(entry.getKey())
.resize(imageView.getMeasuredWidth(),
imageView.getMeasuredHeight())
.centerCrop()
.into(imageView);
The 'dashing of image quality' mentioned above is simply dividing the imageView.getMeasured... by a number like '4'.
First you need to manage the memories allocation ,its a big issue in android as bitmaps takes lots of memories ,for that memory allocation can be reduce by following ways
put all those images which are huge in size to assets folder instead of putting them in drawabable folder . because drawable resources takes memory for caching them .if you load from asset folder the image will not cache .and will takes less memory .
study Lrucache which use for efficient memory management .
put resources in tiny formats for that check TinyPNG
if your images are too large in resolution , then try to use SVG files for images and load SVG file instead of image . check this SVG FOR ANDROID
finally i am not very good in English hope it may helps you.
This post is a little old but I also had this issue recently. Maybe this will help someone else.
General Overview of this massive thread/What helped me.
-Make sure you are using a Singleton Instance of Picasso
-Use fit()
-For large Images or many Images or when used in a FragmentPager/StatePager you should probably use skipmemorycache() and/or largeHeap declaration
Read the thread for more tips. At the time this question was posted nobody had posted this issue on picassos github.
https://github.com/square/picasso/issues/305
The title says most of it. I believe packaging the basic data set into the app will result in a better user experience, rather than have people download files before they can start using the app. This is where one can start losing users. At the same time, 20MB is considered kind of a lot for Android,so I wonder if this will cause issues for some users in using the app.
I am not sure if this will cause an issue. I am an android developer who uses android phone and facebook app in my fone is almost 21MB. It does not cause any issue...However, as a developer a better approach would be to do an app that does not exceed 10MB space(Unless your app is outstanding like Facebook). You can do this by using images of smaller size,making sure you do not have any resources that you are not using(classes,layouts etc)
The size never causes issue but you may consider more:
I am a android developer and a long time Android user too. Not All Android phones have high-end processors to run app faster.
A lot of Android Phones have phone memory of 100-250MB. And the old versions of Android doesn't allow user to install app on SD card. So the user may hesitate to install your App.
Unless it is necessary try to reduce the App size.
As per my personal experience, If you are designing something astonishing and it costs even few hundred MBs on my phone, so i really wouldn't mind to give a try. Since new phones, processors and high storage capacities are continuously evolving and appearing in consumers' hands, so how can we expect applications to remain the same (tiny) in size? Let them grow (but not without any valid reason), and people would still try/buy it. There are no fixed rules or guidelines for limiting the app size, but a directly proportional relationship explains it well:
High-end graphics and feature-rich application ∝ Extra size/memory
What I think is :
The size of the app never creates issue. Again if its an extraordinary app. then surely user will surely get attracted and download your app..
But on the other side just think about the Internal Memory of the phone. There are lots of phone available that has very low internal memory(many have 150 or 180MB as internal memory). May be because of too low internal memory, they wont be able to use your application and hence you may not get big traffic.
You've got a lot of answers here so I'm just going to give you my perspective.
I would be frustrated to say the least if I downloaded a 10MB app and then opened it to find I needed to download another 10MB of necessary materials. Just make the app 20MB so I know what I'm getting into when I start the download.
Only put the bear essentials into the app if it's going to be that big. Don't require users to download high res images, language packs, etc. Just publish the bare minimum that your app requires to run if it's going to be larger than 10MB. You could even publish two versions of your app, the bare minimum at 7MB or the HOLY SH*T package at 20MB, at least users would have a choice when they went to download your app.
Spend some time looking up common practices when it comes to saving space when making an app, every little bit counts and if you can make the same app and save 5MB, your users will appreciate it. If it comes down to a lot of images, consider using this tool; http://www.getpaint.net. However I would suggest reducing the JPEG quality) rather than compress them. JPEGs aren't very squishy.
Going along with #3. Think about universally accepted methods of communication; a sideways triangle for a play button, and X for a delete button, be sneaky...save space. User's love that crap :]
I'm developing a small social networking app that makes use of something like profile pictures. Images are stored on a server and I have scripts set up that will send the image for each user to the app, which then displays it in an image view for each user, and then saves the image to external storage. The way I have it implemented now is that anytime the app needs the image after it downloads it from the server, the app will get the image from external storage unless a user has uploaded a new image (I thought this would be faster than redownloading it from the server every time). However, it seems to be taking longer to get the file from external storage than it does to get it from my server (and the server is pretty slow, running on wifi from 3 floors away...budget constrains :) ).
My question is what is the fastest way to get these images if the user hasn't uploaded a new one. Should I just downlaod it from the server everytime (I'm assuming not) or is there a better place in the filesystem to store the images that makes for faster retrieval?
Loading images from the SD card should be very fast. Some strategies:
Do it only once - Load the images into memory asynchronously when your activity or application starts. You don't want to be hitting the SD card every time your view updates.
Make them small - If you're having performance problems displaying thumbnails in a list, try saving your thumbnails as smaller images using inSampleSize to put less pressure on the decoder.
Use internal memory - I think that internal memory is faster, but it tends to be in short supply. You could certainly store some number of thumbnails in your cache directory to help speed up step 1.
Responsiveness over performance - The golden rule is to remember that absolute performance does not always correlate with responsiveness. Even if the images take a long time to load, choosing cleverly when to load the images can have a great impact on the user's perception of speed.