I have a task object that I would like to track time spent on. I am running a timer counting up for a variable in the task, but whenever I go to update the task inside the database it seems like it somehow gets set back to null even after I confirm that it updates. I was thinking that maybe I am not understanding the database class completely, and making the context that I am calling the database on somehow affects the data inside. Is there any reason that my data is being set to null?
Okay, so I figured this out. The problem was that I was creating multiple instances of the database in one activity. Also, I was using a service that was meant to share data across activities that both affect the data within the database in specific ways. When I passed between these activities, the application was essentially swapping between different instances of the same database, and therefore never really saved the data correctly and led to some weird behavior.
The moral of the story is that you should create one global database for your activity, and try to share the same database between two activities attempting to manipulate the same data.
Related
I am currently facing a problem with persisting object state in an android app.
I have some kind of multi level master-detail flow.
For example, I have a list of Clients. Each Client has multiple Orders and each Order has multiple articles.
Until now I did the following:
When you click a Client in the MasterActivity I write the Client into the Bundle and open the DetailActivity.
In the DetailActivity I read the Client from the Bundle and display it.
This worked more or less fine most times, however it now happens, that an object is too big to be serialized (for example a Client with a lot of Orders).
Therefore I wanted to serialize only the ID of the Client and load it from the database inside the DetailActivity. Usually this approach works fine but I have one situation where it does not work:
The Articles are only saved, when you save the Order (their Master). So if you create a new Article for an Order and you don't save the Order, the Article isn't saved too.
That means, that I always need to have the full object, reloading it
from the database inside the DetailActivity means, that I loose all the unsaved changes. However, persisting it, using the Bundles could exceed the limit (500kB to 1MB).
So my question is, what is the preferred way to persist such data?
A nicer way is to create your own singleton class which points to data you want to transfer between activities.
I suggest DataManager singleton activity which has Article articleToPass
Make the setter set the articleToPass to point to what ever you want.
and the getter or reader, will read fetch the article and nullify the articleToPass.
manage your app data using this DataManager singleton (This dataManager singleton can be initialized either in the extending Application class or MainActivity).
Incase you must persist the object when app is destroyed and loading back:
Create from Article object a DB entry which contains all data you need (I see no reason why saving data you don't need here)
Dump all data to some file (Using Shared Prefs, key and values)
When entering the Details screen you want make a query to a sever of yours requesting all data you need by ID or such.
Convert all object you need to JSON (simply using GSON), and dump the JSON to a file, and load it when you need.
I think the resolutions above are enough :) hope i helped
You can subclass your own MyApp class from Application, specifying it in your manifest. This class is a singleton and is available all the time the android application is running like this (MyApp)getApplication().
So, in a field of this class you may keep some temporary data you need to keep between activities.
You have to check if this field is not null though because the OS can terminate your app anytime. In this case you will have to reload the data. You can keep some index of what data to be reloaded somewhere in the SharedPreferences.
I have an android application in which I am using Content Provider on top of the database. However, I see that database gets created only when I insert the first record in the database through the Insert of Content Provider. In this scenario, if there's an error in database creation that would remain pending till the insertion of a record.
I would like to know if there's a way I can create the database when the app is accessed for the first time, so, any possible errors in the database creation appear at the earlier stage.
Within our app we show a splash screen specifically for the purpose of creating the db and initialising some application singletons. I'd recommend something similar.
You can start a db (on)Create or db (on)Upgrade by calling SQLiteDatabase#getWritableDatabase or equivalent. Remember to perform this on a background thread and use standard eventing / callbacks to understand when this (synchronous) method has completed.
If something goes wrong then you can catch that exception during start-up although you can't really recover by the sounds of it so you'll be best off not catching any exceptions and making sure your critical init code is bullet proof.
I have my MainActivity which gives the user a selection of pages to open, all of which involve downloading some data from the internet and displaying it. To save the user waiting when they choose their page I've made an AsyncTask as a subclass of MainActivity which produces an object DATAwhen the download is complete.
How would I pass DATA on to the SecondActivity in the following circumstances:
The user chooses the SecondActivity before the AsyncTask download has completed.
The download completes before the user chooses the SecondActivity.
the AsyncTask doesn't have to be a sub-class of MainActivity its just been tidy to do it that way so far,
thanks for the help!
Here's one way to do this:
Create a reference to your data in your Application. The Android Application is a good place to store global data. Next, populate the data via your AsyncTask (Watch out for the pitfalls of using an AsyncTask). You can now access your data via a call similar to this: ((MyApplication)getApplication).mydata
As you mentioned, two scenarios can come up. Either the data has been populated, or not. To handle this, use an observer that observes changes to the data. Have SecondActivity register as an observer when the data is null. When the data is available your SecondActivity's update method will get called and you can do whatever you please with it. Finally, make sure to unregister from being an observer.
Hope this helps.
Passing information directly between activities works only if it is Parcellable (via Intent). Almost anything could be made Parcellable but it is not always a good idea especially when the amount of data is large.
The next problem is that your AsyncTask most likely keeps the Context of your first activity alive when it is running longer than the activity lasts. Activity instances are quite often recreated when you rotate the device and naive implementations tend to start another asynctask in the new instance and end up with multiple tasks that download the same data. You would need to pass the reference of a running task between instances of the same Activity.
The simplest solution is probably to create a singleton (or a Service) accessible from both activities that hosts the AsyncTask & loads the data. If it requires a Context use getApplicationContext() since that's safe to use outside the lifetime of Activites.
Activities could register themselves as listeners for "data loaded" events while they are active.
I've recently struggled with AsyncTask and had difficulty having the UI behave while the task was running in the background. While there are comments around that services aren't really appropriate for the sort of thing you're describing, I've found them much easier to work with. You might check intentService as a middle ground. Good tut's can be found here and, specifically concerning intentService, here.
I am trying to understand the possible ways to work with SQLite when there can be multiple threads work on DB.
Based on various responses in stackoverflow and other sites, it appears that there will be locking issue when same sqlitehelper instance is used from multiple threads. In a typical java application, I would expect instance to mean single object of type sqlite helper to be used by different threads of application.In such cases, the locks ,I guess, are a matter of correctly using the synchronized blocks. [Correct me here as I am not comfortable with this way of looking at sqliethelper instance here]
My concern is with sharing same data base : when one instantiate sqlite helper in different threads [ie each thread has its own object instance] but working on same Database [this I guess is more inline with having same db instance].
In such cases I'm getting frequent database lock errors. This occurs even when the threads are working on different tables of database.
In my application database can be updated by user interaction through application or by getting data through server [periodic synchronization]. And some time when synchronization process and user activity overlaps, I get the lock issues. As this pattern of data processing seems to be common in application synchronizing with server, would like to know how do lock issue due the concurrency is to be handled.
I would like to understand this since if this is bound to happen always then probably need to make only one handler over database and implement queue over that to avoid lock. But that will mean the complete application needs to be aware that the database may not get updated immediately and they need to implement listener to know when the data is actually updated in database.
thanks
pradeep
As far as I know sqlite is intended for single process usage. No matter what you will always need to access the database from one thread at a time. You can do selects from multiple clients but can only write from one at a time. And other readers and writers will ahve to lock in the mean time.
As a side note - database access can hardly ever be considered instantaneous.
I'm currently building an android application with quite a few different connected activities. In each activity I've got a private updateView() method to update all the textViews and stuff on that screen. This gets called in the onResume() method so that each time the activity comes to the front it's views will be updated.
Is this the right way to do things or is there a more standard pattern for keeping your views in sync with the data?
I think that you are doing this correctly. onResume would be the perfect time to update your views, I assume you are only updating if there is actually new data to be displayed?
If retrieving the data during the updateView method takes a long time then you should do it in an AsyncTask to avoid clogging the UI Thread which will make your app hang.
In fact any data retrieval like getting data from the web or reading from your apps database should be done in an AsyncTask. This is because even if your data retrieval seems to take milliseconds on your device it may conceivably take longer on another, less powerful device.