In my chat app, I am adding the ability to log chats. The logs are saved on the sdcard and one BufferedWriter is kept open for every person/channel chat is done with. I'm wondering what effects this might have have on the sdcard and its life.
My BufferedWriter's buffer size is to 1024, I'm also wondering if that is too small or too big.
Flash memory cards have an endurance of about a million write cycles per area and probably include wear levelling which basically means trying to write to different areas so specific spots dont wear out.
So after about (sizeOfSDCard/sizeOfYourData)*1,000,000 writes, you will have ruined their card.
Practically, this means you probably aren't going to cause any harm.
Related
I'm having a bit of trouble thinking of an efficient solution. There are a few problems I am foreseeing, the first being...
OOM Prevention
If I wanted the past 30 seconds or even 5 minutes it's doable, but what if I wanted the past 30 minutes or full hour, or maybe EVERYTHING? Keeping a byte buffer means storing it in RAM. Storing over a hundred megabytes sounds like Virtual Memory suicide.
Okay so what if we store a Y amount of time, say 30 seconds, of the previously recorded media to disk in some tmp file. That potentially could work and I can use a library like mp4 parser to concatenate them all when finished. However...
If we have 30 minutes worth that's about 60 30-second clips. This seems like a great way to burn through an SD card and even if that's not a problem I can't imagine the time needed to concatenate over a hundred files into one.
From what I've been researching, I was thinking of using local sockets to do something like...
MediaRecorder -> setOutputFile(LocalSocket.getFD())
Then in the local socket...
LocalSocket -> FileOutputStream -> write(data, position, bufsiz) -> flush()
Where the background thread handles writing and keeping track of the position, and the buffer.
This is purely pseudocode and I'm not far enough in yet to test this, am I going in the right direction with this? From what I'm thinking, this only keeps one file which gets overwritten. As it only gets written to once every Y seconds it minimized IO overhead and also minimizes the amount of RAM it eats up.
Video Length to Buffer Size
How would I obtain the size the buffer should be from requested video size. It's strange since I see some long videos that are small but short videos that are huge. So I don't know how to accurately determine this. Anyone know how I can predict this if I know the video length, encoding, etc which gets set up from Media Recorder?
Examples
Does anyone know of any examples of this? I don't think the idea is entirely original but I don't see a lot of them out there and if it does it is closed source. An example goes a long way.
Thanks in advance
The "continuous capture" Activity in Grafika does this, using MediaCodec rather than MediaRecorder. It keeps the last N seconds of video in a circular buffer in memory, and writes it to disk when requested by the user.
The CircularEncoder constructor estimates the memory requirements based on target bit rate. At a reasonable rate (say 4Mbps) you'd need 1.8GB to store an hour worth of video, so that's not going to fit in RAM on current devices. Five minutes is 150MB, which is pushing the bounds of good manners. Spooling out to a file on disk is probably necessary.
Passing data through a socket doesn't buy you anything that you don't get from an appropriate java.util.concurrent data structure. You're just involving the OS in a data copy.
One approach would be to create a memory-mapped file, and just treat it the same way CircularEncoder treats its circular buffer. In Grafika, the frame data goes into a single large byte buffer, and the meta-data (which tells you things like where each packet starts and ends) sits in a parallel array. You could store the frame data on disk, and keep the meta-data in memory. Memory mapping would work for the five-minute case, but generally not for the full hour case, as getting a contiguous virtual address range that large can be problematic.
Without memory-mapped I/O the approach is essentially the same, but you have to seek/read/write with file I/O calls. Again, keep the frame metadata in memory.
An additional buffer stage might be necessary if the disk I/O stalls. When writing video data through MediaMuxer I've seen periodic one-second stalls, which is more buffering than MediaCodec has, leading to dropped frames. You can defer solving that until you're sure you actually have a problem though.
There are some additional details you need to consider, like dropping frames at the start to ensure your video starts on a sync frame, but you can see how Grafika solved those.
I'm going to write a music player for android which satisfies specific needs (which doesn't matter to my question).
I'd like to identify internal playlists with directories (inside of one main directory) on sdcard because I know my users will set up organized directories. So simply reading all audio files in a single list to let the user create playlists manually afterwards would probably be annoying.
I'm wondering whether it's worth to generate a hierarchical playlist file for this purpose.
My current plan is to run a "library inspector" when the app is started. This inspector will use a "library state" containing of hierarchical data of the form
String filename;
long modified; // timestamp of last modification
to check the library recursive for the need of creating a new playlist file. If this matching check fails, this hierarchical file (metadata: title, artist, album, ... - for example xml) is created including a new "library state". This file should prevent to read all the metadata every single run of the app.
To make that clear: I'm searching for an efficient way to play music - but safe battery!
Since I'm new to the development of mobile apps, I'm not very familiar with battery saving. Is it that more saving to read one file instead of recursive metadata reading? Or maybe I'm about to overdo things? Do you know some strategies of established applications?
I'm very interested in your thoughts :) and I hope my bad english doesn't prevent your understanding ... I'm sorry for that.
Thank you!
Max
I can't answer from the perspective of using MediaStore or SQLite, but can give you some suggestions about minimizing battery usage.
Don't use recursion. Recursion is structurally compact but awful in terms of efficiency. Every call is very expensive due to accessing stacks, possible doing context switches, etc. If the recursion is very deep, there are also issues with regards to disk usage, page swapping, etc.
Use an efficient searching algorithm for any large list. The faster you complete what you're doing, the more the processor is idle, the deeper the power state, the more power savings.
Gather your searches / accesses together as much as possible. For example, if you have to do 3 searches, each 1 second apart and taking .5 seconds to execute, you'll keep the processor active in a high power state for over 4.5 secs before letting it rest and drop into a lower power state. If you gather your queries together, you spend 1.5s in a high power state, and 3 seconds in a lower power state. Roughly speaking, you use <1/3 the power.
Use on board memory as much as possible. I don't know how slow accesses to sdcards are, but it'll slow down your algorithm and possibly increase your power consumption.
Try to setup your database entries and other data structures so that they are naturally aligned with your processor's caches (e.g. 16B aligned). That will speed up routines by a significant amount (L1 cache access might be 1 cycle, L2 10 cycles, and memory 100 cycles - these values are illustrative but ballpark). And the fast your routine, the more idle, and the greater the power savings.
My timing durations (e.g. 1 sec apart) are just for illustration purposes. There are multiple idle states and different rules for dropping into those states that can make a real illustration very complicated.
I don't know much about the power efficiency of databases. I do know there are some data bases designed for mobile and low power devices. Unfortunately, I don't recall what they are. (Don't quote me on this, but I recall something about Berkeley and real time.
PS Your English seems excellent.
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.
all
When I try to read some media file from sd card after the first time I insert to the device, the read performance is much worse than the second time, does anybody have any idea about this phenomena, and how can I avoid this problem, I tried open and fopen, but the results are the same, I just want read performance is the same, no matter when I insert SD card, thanks
Using O_DIRECT (see open(2)) when opening the file will bypass the buffer cache. This is often not a good idea, but I would expect it to be more consistent from run to run.
Keep in mind that using O_DIRECT requires that the memory read into be SC_PAGESIZE aligned and read in blocks which are multiples of SC_PAGESIZE.
Are you saying it's worse for the first read than subsequent reads before you remove the device? If so, this is normal - it's due to buffering. Basically the system is using the system RAM to speed up the perceived speed of the device.
If you remove the card after unmounting it and then put it back and remount it I would expect the first read would again be slower, then subsequent reads would appear to be faster again.
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 :]