Android FileOutputStream method 'ignored' - android

I use three files for storing of local data, for my app, two of which get checked on app start-up and updated remotely (if a newer version is available or the files do not yet exist). The third is for user data that can periodically be stored while the app is running.
All three use the same method to save the file:
public boolean setLocalFile(String Filename, String FileText, Context con) {
try {
FileOutputStream fos = con.openFileOutput(Filename, Context.MODE_PRIVATE);
fos.write(FileText.getBytes());
fos.close();
return true;
} catch(Exception e) {
handleError(e); // local method that simply does a System.out.println
return false;
}
}
Now the third file writes fine, but the first two (that are checked and written on start-up) don't write at all. In debug, it appears as if the setLocalFile method is completely skipped without throwing an exception or crashing the app and the only error logs reported appear to be:
07-11 16:14:13.162: ERROR/AndroidRuntime(1882): ERROR: thread attach failed
07-11 16:14:18.882: ERROR/gralloc(62): [unregister] handle 0x3bfe40 still locked (state=40000001)
I've not found anything useful online, in relation to these either, unfortunately.
It's got me stumped - I have no idea why it's not writing in this particular case. Any ideas?

A belated update... Giving the code where this issue was occurring probably would not be too practical as I suspect one would practically need all of my code to examine it fully.
My variable names began with capitals largely because I've just been getting back into Java again after about 10 years with other languages, so it took me a while to get back into the swing of things - not pretty, but I would be surprised if it would have made a difference. Nonetheless, thanks guys for the responses.
The background to the issue was that I had decided to handle the data held in these files as class objects. So the Drafts object would hold all the draft documents and the class constructor would call the getLocalFile method and store it locally in the class, allowing me to work with it (using various get/set type methods), before writing it again to a file with a 'commit' method (calling setLocalFile).
There were various such class objects being called, but never more than one instantiated for each data file. What stumped me was that everything was working fine, except the FS operation was simply being ignored. Once I accessed the files directly (ignoring the class wrappers I'd written) the problem vanished.
The class wrappers work fine in other parts of the app and this problem only occurred in the one, complex and rather intensive, section of it.
As I said, I'm only getting back into Java after an extended absence (and much has changed), but looking at the issue and how it 'resolved' itself, my guess is that it was some form of thread / memory issue - essentially I was accessing the FS from too many objects and eventually it decided it didn't want to play anymore.
The problem, as I said, is resolved, but it bugs me that the solution did not allow me to wrap my data objects more elegantly. If someone might suggest what may the cause / solution for this, I'll happily try it out and report back, otherwise this response may help someone with a similar problem in the future - at least to find an inelegant solution...

Related

AWS S3 Java SDK: detect time/clock skew programmatically?

My Android app uses the AWS Java SDK for uploading user photos to S3.
Whenever a user's phone's clock is 'skewed', this causes all transfers to fail. This is a well documented aspect of S3:
http://aws.amazon.com/articles/1109?_encoding=UTF8&jiveRedirect=1#04
It appears that the upstream S3 service reports this error quite clearly:
HTTP Status Code: 403 Forbidden
Error Code: RequestTimeToo-Skewed
Description: The difference between the request time and the server's
time is too large.
However when using the Java SDK, it seems as if the informative 403 code is lost ... and I have only an opaque "TransferState.Failed" to go by (which incidentally is the same error if internet connectivity is lost, if it times out, etc...).
As far as I can tell from the docs:
http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/index.html
http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/transfer/TransferProgress.html
http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/transfer/Transfer.TransferState.html
http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/transfer/Upload.html
There is no way to get the additional "RequestTimeToo-Skewed" metadata about a transfer failure.
Am I missing it? Is there any way to get additional error information when an S3 transfer fails using Amazon's Java SDK?
UPDATE #1:
A commenter kindly highlighted that I should clarity two points:
I am actually using the AWS SDK for Android (which seems very similar to the Java SDK, but is nonetheless distinct)
I am using the TransferManager class to perform my upload. Apparently, this is a high-level class that wraps the lower-level AmazonS3Client ... and this lower-level class should expose the error reporting I need, but I am still investigating the exact tradeoffs involved between TransferManager and AmazonS3Client. As far as I can tell, there is no way to get progress information via the (synchronous) AmazonS3Client.putObjectRequest which would be a blocker for me...
UPDATE #2:
My sincere thanks to Jason (of the AWS SDK team) for stopping by and helping me out here. The important information is, indeed, available as properties on an AmazonS3Exception if you use certain methods. The docs had originally confused me and I thought that a manual Thread.sleep() loop was required to poll status (and thus I could not leverage waitForCompletion or waitForException), but if you use ProgressListener on PutObjectRequest you can get full progress callbacks and the error-fidelity of AmazonS3Exception.
these two methods should help you out:
Transfer.waitForCompletion()
Transfer.waitForException()
If you detect that your transfer has failed based on a transfer progress event, you can simply call Transfer.waitForException() to be returned the exception that occurred. That exception will be an AmazonServiceException in this case, with all of the info that you need to see that the real problem was a clock skew issue.
Alternatively, the Transfer.waitForCompletion() method will unwrap the original exception from an ExecutionException and directly throw the original exception, just as if it'd all been happening on one thread. This might be a more convenient approach if you want to use a catch blocks to catch different types of errors cleanly and elegantly.
I disagree that the "catch Exception" block is "brutally broad". The point of that code is to catch any error that happens, mark the transfer as failed and rethrow the error so that the application code can know about it. If it were less broad, then that's exactly the case where exceptions could sneak through and transfer progress wouldn't be updated correctly and would be out of sync with reality.
Give those two methods and shot and let us know if that helps!
Well, I have debugged Amazon's SDK and I'm sorry to say that this information is being swallowed internally. Perhaps I will try to submit a patch.
Details: an AmazonS3Exception is being thrown internally which does in fact accurately report this exact error scenario, but a brutally broad try catch ( Exception e ) consumes it and washes away the specificity.
Here is the guilty try-catch:
https://github.com/aws/aws-sdk-java/blob/master/src/main/java/com/amazonaws/services/s3/transfer/internal/UploadMonitor.java#L145
Here is a screenshot showing that an AmazonS3Exception is correctly thrown with the right info...

How to force Android app to deallocate all memory?

I have an annoying problem:
I'm fetching a lot of GeoJSON data from a server. This works, even with 16MB heap and even if I start and stop the app several times. The memory consumption stays constant and never exceeds. But there is a case where I exceed the 16MB heap. I'd like to describe it shortly:
The app is used and "quit" by home button, so the app resides in the background and is not destroyed yet. When the app is resumed, my "controller" which is a part of my app, checks for new GeoJSON data. If there is a GeoJSON data update, the app downloads and processes it and here the problem begins. If the app was already started before and is resumed from background the heap size of 16MB is not enough for the following code (if and only if the app is resumed from background instead of a fresh start):
private synchronized String readUrlData(HttpURLConnection urlConnection) throws IOException {
Log.i(TAG, "Start reading data from URL");
urlConnection.setReadTimeout(1000 * 45); //45 sec
Reader reader = new InputStreamReader(urlConnection.getInputStream());
StringBuilder sb = new StringBuilder(1024 * 16);
char[] chars = new char[1024 * 16]; //16k
int len;
while((len = reader.read(chars)) >= 0) {
sb.append(chars, 0, len);
}
reader.close();
Log.i(TAG, "Finished reading data from URL");
return sb.toString();
}
I get OutOfMemory either in append() or in toString(). Obviously the app takes little to much memory for this when it's somehow used before. I already tried to find a more resource friendly way for the code above but there is no solution. Again, if the app is started from new, there are never problems. And I'm absolutely sure that I don't have any memory leaks because
I checked this part and more with MAT and there was never more than 1.6MB occupied (this is the GeoJSON data).
I performed this use case several times consecutively with 24MB heap size.
If there would be a memory leak, it would have been crashed after the 3rd ot 4th time with 24MB heap, but it ran without problems.
I know how to avoid the crash. I could show an AlertDialog to the user which tells him that there is new GeoJSON data available and he needs to restart the app. But there is a catch. If the application is "terminated" by Activity's finish(), the application still remains in memory so when it restarts, the crash comes again because the memory is never deallocated (at least I can't rely on it in most cases). I already figured out that System.exit(0); instead of finish would free all memory because it kills the whole app, so no crash occures after restart with the new GeoJSON data. But I know this is no good solution. I already tried System.gc() on important parts but this doesn't work either. Any ideas how to deal with this problem? Probably I need something like restarting the app with deallocing all used memory.
Another solution could be to redesign the code above but I don't think that it's possible to get more MBs out of this.
If I don't find a reasonable solution for this, I will use System.exit(0) when heap is 16MB (I think there is a way to check that) to restart the app.
here are some ideas :
as soon as you know there is anything to read , set the old data to null so that it will be GC-ed .
use a service that does this task , that will run on a different process (thus having at least 16 mb just for this task) . once it handles the data , move it in some way to whatever component that you need , while null-ing the old data before.
decode the data as you get it , instead of getting all of it and then decode it .
compress the data so that the while decoding it , it will decompress it on the way .
use an alternative to json , such as google's protocol buffers or your own customized data type .
most of the devices out there have more than 16 mb in their heap memory . you could simply set the min sdk version to 8 or 10 since most devices that have more memory than this also have a higher API .
Thanks for your answers. At the end I decided to let System.exit(0) in this one special case because the data is hardly ever updated and even if, it must be coincidence that it happens exactly when someone has the app running in background.

Application crashes when application resume for long time

I am creating an android application. It holds a downloading process from server. It's running fine until the application runs and maintains the data without any crashes, but now I am stuck up with the problem as described below
When the application minimizes by pressing home button and after a long time, when I open the application all the data in the application are deleted. It gives me a "Null Pointer Exception"; even the ArrayList value are deleted and it gives a 0 sized arraylist.
I am opening the application after maximizing from the home screen through OnResume only, but it didn't call itself.
I don't know why this problem occurs. Can anyone please suggest me a solution and point me what am I doing wrong?
Yes, it's true - as #paradx said - that the Garbage Collector throws away the data while the app is in background. Finally I found a solution based on #paradx suggestion, as data are stored in SQLite or savedInstanceState
Just pass some of static values through the
intent.putExtra("static key","static value");
Then static hashmap are written in a file and retrieved for later use. Now the application does not crash for this problem.
I have posted this solution so that someone might use it.
My guess is, that the garbage collector throws away your data while your app is in the background. try saving your data either to the built in SQLite database, or to the savedInstanceState bundle in the onSaveInstanceState() lifecycle method and load it back in the onRestoreInstanceState() method.
Did u use the apache HTTP client or the UrlConnection?
See Apache http client or URLConnection
Maybe the wrong use could lead to such an NPE.
Could you also please post your logCat output?

Message queue solution for activities that come and go on Android?

Lets say I have a Service S and Activity A. S downloads data for A (or handles some long running work, whatever), but A is not always present. I don't want S to hang around when it's job queue is empty: S should post the results of the finished works to some kind of a mailbox for A, so A can pull the messages when it comes back again.
Can this be achieved without using SQLite of file storage for the implementation of the mailbox? I'd prefer some faster mechanism, write operations tend to be quite slow on a device. I thought about using a simple static list inside the ApplicationContext, but afaik relying on the ApplicationContext results a risky/fragile solution.
Could anyone recommend a pattern for this problem?
Can this be achieved without using SQLite of file storage for the implementation of the mailbox?
Not reliably. Either it's a file, or it might be nuked before A comes back again. Remember that your process -- where all your static data members and the Application object reside -- does not live forever. Once S shuts down (which is a good thing, thanks!), Android is welcome to terminate the process, taking your "mailbox" with you if it is solely in RAM.
You could persist it to disk yet keep a singleton or something around as a cache, so if A returns quickly you can skip some of the I/O. Or, if it does not really matter much if the messages exist for A, you could keep them in RAM and simply shrug your shoulders if the process gets terminated first.

android application memory leaks

I am using kind of results search engine, problem is to remember the searching criteria i made singleton static class which keeps only one instance.
In my application there are lots of class level private variables, lots of public static variables, a big util class which contains only static final methods.
problem is my application get crash any time any where any spot and interesting thing is crash code always surrounded by try{} catch(Throwable e){} block but never catch, i think it may be memory full issue.
I want to discuss one sample case, on the result page i also display result related image, i download image from web and using drawable i place image in the imageview, i created static hashmap to reuse images, some time after downlaod 5 images application crash some times click on a result get user to new detail screen get crash and all code surrounded by try catch block, i am new to mobile program this thing has become night mare to me.
Last thing, On emulator hardly application crash but when i try to test the application on device, i am using samsung glaxy android supported to test the application it goes smoth and suddenly it start getting crashed, and after crash android relaunch the activity that throws null pointer exception on every click and caught by try{}catch{} block i think after crashing android dealocate all objects only keep the UI objects thats why when after crash i auto launch the activity clicking causes null pointer exception.
how can i stop relaunching crashed activity ????
Here are some suggestions that might help track down your issue(s):
introduce logging - use Log to log useful (debugging) info
avoid empty catch blocks - use Log.e() to log your exceptions
reduce functionality to a minimum for debugging
In order to get a useful answer on Stackoverflow you'll have to do all of the above and provide a more detailed problem description (e.g. a specific stacktrace in your logcat output).
Also, there is an article about Avoiding Memory Leaks that might be interesting to you.

Categories

Resources