ANR keyDispatchingTimedOut in onPause - android

I have an app that allows users to input a lot of data while on one particular Activity screen. If the user navigates away from this screen suddenly for any reason, I save their data to the app's SQLite database. This app has been out for nearly 2 years and has never encountered the ANR timeout, but within the last month I've received 2 reports in the market.
In one case the problem occurred when trying to close the database. In the other case, the problem occurred when trying to open the database. I can't reproduce the problem at all, but I see the exact sequence of steps that are executing, but my problem is I don't know what I could possibly change. Both also revolved around securing a mutex for the database I don't create the mutex myself, this is a system thing.
Basically, onPause gets called, the database gets opened, I write the data to the file, and I close the database. As far as I understand it, this is the proper way to do things if your data isn't able to just be stored in SharedPreferences (which my data can not be).
I don't understand why an open or close of a database would take so long, so what are my options here? My only assumption is that these problems are arising from users who have had the app for a very long time, and thus their database files have grown extremely large, and perhaps it makes the system take longer to lock down the database file (I'm just guessing here).
I thought of maybe starting an AsyncTask from onPause, but that seems wrong. Any suggestions?

Related

Android app to write to a file every 5 ms

I have an android app that needs to store critical information coming from a sensor. The sensor updates data every 5 ms. I need to persist each of these data points on internal memory in text files.
In the current scenario, I am collecting data points for 2 seconds in memory and then writing to the file at the end of 2 seconds to save battery life. However, under situations where the app crashes, I am loosing the critical data points.
Does anyone have any suggestions on how to handle this?
Is it a good idea to write the data point to the file every 5ms. Would this significantly reduce the battery life and increase the load on the CPU? If anyone has come across a similar situation, can you please share how you resolved the issue?
I would suggest you to study the reason of your app crash. If your app is crashing because of internal exceptions there is a better way of dealing with this thing.
Write a good exception management and use this blocks to write data to internal memory whenever there is an exception generated. Re-start the app after the data has been successfully written.
It you app is crashing because of external reasons and you are unable to catch exceptions, you have to think of some other way.
As your App is critical, I would look into setting up a DefaultUncaughtExceptionHandler by calling Thread.setDefaultUncaughtExceptionHandler in your Application class. This way in the handler, you can write all unsaved data, AND you can restart the app for continued handling of your critical data. I would put some seconds counter in there, to prevent an infinite loop of crashes. The Open Source ACRA library uses Thread.setDefaultUncaughtExceptionHandler, so you may get some idea from there on how to use it.
An additional idea is to write the data using a service in a separate process, search for "Remote Service". This way, even if the app crashes, the service will still be alive. You will have to setup some functionality on how to share the data between the app and the service. If the app is really critical, I would setup 2 remote services, one that gets the info from the sensor (and caches it as a backup until confirmed that it's written), and one that caches the data and writes it every few seconds. Each service should also have a DefaultUncaughtExceptionHandler as above. This is in addition to the actual app, that will have the user interface. Though it is a little waste of resources, but for critical data it is not wasted.
i donot think there's a good method. What more important is to avoid crash maybe
Instead of writing to a file every 5 ms, which will be a costly operation, you can save data to SharedPreferences every 5 ms and every 2 sec, save the data from SharedPreferences to a file. SharedPreferences content won't be deleted even if app crashes and hence you will not have any data loss.

How to handle data missing after resume

I got some issue when I developing an App.
After I minimized the app or turn the screen off, and open lot of other apps or reopen the phone after a long time.
When I restart my app, it try to resume and keep showing the same page(with fragment).
But the data I need was already been destroyed so it will be null.
The data is an object array, I know maybe I can store them in db.
But due to the data will update every time user click something.
So I don't want to save it into data base, I guess that means lot of storage I/O witch is not necessary.
I'm wondering if there is any solution to restart the hole app when things is destroyed?
Or the only way to make it happen is I handle the null array and do the reload myself?
I don't really want to do that cause I guess that will bring me many unexpected issues cause the data is related with many pages.
Too many situations I have to consider when do switching pages.
Are there any advice?
But the data I need was already been destroyed so it will be null
That is because your process was terminated and you did not save your state.
But due to the data will update every time user click something
Or, you could fork a thread to save the data as part of your onPause() or onStop() methods. There are many possibilities between "never save" and "save on every click".
So I don't want to save it into data base, I guess that means lot of storage I/O witch is not necessary
If you want the data to be there 30+ minutes after the user left the app, your choices are to save the data locally (file, database, SharedPreferences) or save the data on the Internet somewhere.
For small amounts of data over shorter time periods, you could put the data in the Bundle supplied to onSaveInstanceState() and then pull the data out of the Bundle again later (e.g., in onRestoreInstanceState() of your activity). You already should be doing this to handle screen rotations and other configuration changes.
I'm wondering if there is any solution to restart the hole app when things is destroyed?
You are welcome to add android:clearTaskOnLaunch="true" to your launcher activity, to indicate that you always want to start over from scratch whenever the user leaves your app and tries to come back to it. Users will not appreciate this, as this means that they will lose their state even for being out of your app briefly (e.g., a quick reply to a text message). This attribute does not terminate your process, but it will force the user back to the launcher activity and will eliminate any other activities that had been in your app previously.
Or the only way to make it happen is I handle the null array and do the reload myself?
That is what developers normally do, yes.

Android SDCard I/O Managing Mount and Unmount

I know there are various version of this question asked, but I was having trouble getting a clear answer on what the best approach is for my problem.
What I am doing is I am creating a SQLite database on the SD card. I want to be able to query from it and write to it.
The question I have is what is the best way to manage when the SD card is unmounted. I am totally fine with my application closing like the stock MP3 player does. However, I want to make sure any write action to the db do not get partially done.
One thought I had is the use beginTransaction, mark it as successful, and then call end transaction. The question I have is what happens if end of transaction does not get called. Can that potentially lead to data corruption? Also, I need a little help understanding what to listen to or hook into to get notification of the sd card being unmounted.
Thanks
That is the great thing about transactions in databases - you almost never need to worry:
"All changes within a single transaction in SQLite either occur
completely or not at all, even if the act of writing the change out to
the disk is interrupted by
a program crash, an operating system crash, or a power failure."
Taken from http://www.sqlite.org/transactional.html
The disk being removed on which the database resides should (in the worst case) behave like a power failure while writing the data to the disk. The database will discard that data on next startup.
Thus, as soon as your transaction is committed using commit or end transaction and the method call executing your statement returns all data has been stored. Otherwise NO data from your transaction will have been stored - both cases leave you in a consistent state.
Beware of the only catch: You will need to make sure that all statements you need to execute together (i.e. atomically) must be within one transaction!

Detect when application is closed

I want to know when the app is closed, because I need to erase a Database when the user shutdown the app, just in the moment when the user close the app is the right moment to erase the SQLite Database, how can I detect this?
This is a flawed design idea, which reflects a misunderstanding of the system - when the process overall dies, it's dead, meaning your code is no longer running.
You can do some tracking and have the last onDestory()'d activity do the cleanup as a courtesy, but don't assume that it will always actually happen (the method is not always called). If having a stale copy is a problem, clean it up on the next run.
That said, you can try using the ndk to provide a handler for process termination signals, but still I wouldn't count on it working in all cases. The limited potential to gain any sound functionality from this would probably not justify the effort unless you are already familiar with the concepts involved.
And do not for a minute mistake cleaning up for a security mechanism, as the file is there while your app is running, and would remain if your app terminated in an unexpected way.
Supposing you don't finish() your main activity, clearing your database inside the onDestroy() method of that activity might be the closest of what you want to accomplish. As has been pointed in the comments, refer to http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle.

Why would an android user report "Force quits every time I load"?

I'm trying to guess why a user would report "Force quits every time I load"
The problem does not occur for all users, especially not me.
The system constructs a database when it first loads. I suspect that user's phone does not have enough memory.
Questions:
How can I verify that the system has enough memory to store a small database?
What else might cause a user's particular system to force quit on startup?
Wrong answers or things I've tried thus far:
The user's hardware is probably different than mine
The user's software and available memory is likely different as well
The data is already loading in its own thread, with a progress dialog showing
Add some smarts to your app to send you stack traces when the app crashes in the field. That'll narrow down the specific problem and can help you tailor your efforts to clear it up.
Sounds quite odd, does a freshly booted phone give the same error?
Also ask the user to check available storage, might be out if space.
If the UI thread gets frozen for a period of time, then it will show that dialog. Try running the task in the background using an AsyncTask.
Edit: I'm assuming it's this error message.

Categories

Resources