When to load database data into an adapter - android

I have a simple personal application I'm working on that queries some records in an SQL Database and populates an adapter for a listview and is basically working fine... but I've began to wonder if I'm doing certain things at the right point of the framework.
Currently I'm loading everything up during onCreate(). In theory, I could be loading up quite a bit of data, so I wanted to possibly throw up a ProgressDialog while the information is being added to the adapter, but I ran into some odd threading issues with the Cursor. Ultimately, I launched a Progress Dialog near the end of onCreate(), followed by sleeping on another thread and calling a method to load my data with runOnUiThread() following the short sleep time, having the end of that method dismiss the Progress Dialog.
This works, but it's brought me to whether or not I should be loading database data during onCreate... or whether it should be moved to onStart() or onResume(), adding in code to clear the close and open the database, clear and repopulate the adapter as necessary as other Activity's are started and finished. Or would all that be unnecessary and I should just keep the adapter populated during onCreate()?

Reto Meier's suggestion to use an Application may suit your needs. Take a look at Activity restart on rotation Android

Move it to onResume, as if you stop the activity you can destroy the adapter and fill it back when to resume the activity.
It helps to save memory and also helps to update the adapter if data has changed.

Related

Android how to update a listview periodically

I have an array adapter which is used in my listview. The adapter is periodically updated by fetching or removing contents from a server. I have used a scheduledthreadpoolexecutor to periodically update the adapter and then use adapter.notifydatasetchange();
The list view gets refreshed and removes any items etc, but for example if two items where removed from the list when I scroll the listview on android and get close to the end of the listview the application crashes. I guess something does not get updated in the listview and it things that the size of the list is the initial size.
Do you have something to recommend?
Regards,
Aris
Hi all,
I actually found a solution to my problem and forgot to check here for any replies.
Thank you all for your suggestions.
Basically scheduledthreadpoolexecutor called a runnable (lets call it updateRunnable) to do the updates.
What I did was the following:
In the updateRunnable, when it gets the new data and stores them in the array adapter, it then calls another runnable (lets call it updateListView) using runOnUiThread and in updateListView I set the adapter of the listview.
This solved my problem
If your data is at all database-like, which I assume, given your use of a ListView, then you'll want to refactor your background service into a model that uses a ContentProvider and SyncAdapter to stay in sync with the server, and then automatically notify the ListView through binding it with a CursorAdapter which uses its implementation of ContentObserver to automatically update the list when the underlying DB changes.
Why does ContentResolver.requestSync not trigger a sync? tells you how to set up the ContentProvider.
How to handle REST calls, data persistence, syncing and observing ContentProvider tells you a little more about how list update notification operates once the ContentProvider is syncing.
It's a lot of infrastructure work to get set up, but once you do, there's so much that's wonderfully automatic about the SyncAdapter model.
I had a similar problem once. Since the ListView keeps updating you can
1) display the Listview just as the activity starts in OnCreate, and
2) call this SAME activity so as to display refreshed data in the listview.
but after calling the same activity again, finish() the current instance first immediately since you can get multiple instances of it one over the other.

Update ListView of previous activity in background

I have question regarding my previous ListView activity.
I have my ListView which is continue updating using socket connection, now when I click on any of the list row i can go to my next screen now when i come back to my previous ListView screen my ListView is start updating again but i want to keep updating my ListView in a background when i am on my nextscreen.
Something like i want to keep my previous screen alive when i am on my nextscreen.
Sounds to me like your the code you are using to load the data for your ListView is tied to your Activity.
For instance you have an AsyncTask or Thread in your Activity that cointains your ListView and you use it to download data, or do whatever is needed to get the data to populate the list. I also assume you start it in one of the Activity lifecycle methods e.g. onCreate().
If that is the case then you should consider seperating the code used for getting the data for the list from your activity code.
One way to do this is to use a Service which will be able to run independantly of the rest of your application and do all the heavy lifting involed with fetching the data for your list. You can communicate with the service from anywhere in your application. The Service can save the data to a database. Then all you have to do in your Activity is query the database and populate the adapter to get the latest data without much delay.
You can read more about services here:
http://developer.android.com/reference/android/app/Service.html
You could (and probably should) do what Paul suggested or you could change to way you switch your screens by using Fragments or a ViewFlipper. This way you still run your AsyncTask or Thread while doing something else on a different page.

Android:ListView not displaying items when power button locks the screen during AsyncTask

I have a Async Task that creates a HashMap to create a Adapter to populate ListView. I have a progress dialog that shows during doInBackground method.In onPostExecute() method, I dismiss the progress dialog and call a method that populates my listview with the list of items saved in doInBackground method.
This works fine. But I noticed something strange:
The issue I see is, if I lock the screen when the progress dialog is about to be dismissed (in onPostExecute), the listview does not display, even though it has non-empty items in it. I verified it in logcat messages and when I debugged.
Is there a possibility that a screen lock (I do this my pressing power button once) blocking UI thread? How can I resolve the issue and make sure ListView displays its items?
Code for onResume():
#Override
protected void onResume(){
super.onResume();
if(MyAdapter !=null){
pull_listView.setAdapter(MyAdapter);//pull_listView is listview
MyAdapter.notifyDataSetChanged();//MyAdapter is the adapter
}
}
This situation illustrates the downside of using AsyncTask to do background processing. In some cases, an IntentService may be a better choice, especially if you think the background work is going to take some time. An AsyncTask ties the background work to the current Activity, while an IntentService is completely decoupled.
The Android training class Running in a Background Service shows you how to set up an IntentService, request work, and notify your Activity when the work is done. Passing data from the IntentService to the Activity is a bit more complicated, but there are options.
onStop() will be called when your screen goes out as per the Activity Lifecycle. You could override onStart() or onResume() and put a check in there to see if your data has been populated. If not, populate. You may even want to overide 'onStop()' to save data if the screen goes out.
Edit
In this particular situation, I would think onResume() or onStart() would be fine but onResume() is usually the safest because it is guaranteed to get called before the Activity is shown as illistrated in the link I gave. What kiind of a check you want to use is up to you and depends on how you handle evrything. However, if your AsyncTask is an inner class of your Activity class the you could simply create a boolean member variable, say boolean isDone=false; change this to true in your doInBackground() or onPostExecute() then your onResume() knows the data Is loaded. If its false then you can try to get data again. Hope this makes sense and can help

Android - How do i execute code *after* a process is loaded

Basically when a menu item is pressed in my app it takes the user to a new screen.
But now i want to get a little bit of data online(a time/date) that will display somewhere on the page once it gets the data.
At the moment the new screen doesnt load until the app gets the data which leaves a couple of second pause instead of loading the screen instantly and then showing the downloaded data when it finally has it.
Ive tried using the onStart method since that gets called after onCreate so i thought the page would be created and displayed and then onStart gets called but that doesnt happen, theres still lag between it loading because its getting the data online and then displays the page with it already loaded.
How can i sort this?
Thanks
For any kind of loading operation you should consider using the AsyncTask in combination with the ProgressDialog in order to inform your user that you're performing something in the background.
Remember that you can only interact with the UIThread in the onPreExecute() and onPostExecute() method of your AsyncTask.
So in your case you'll probably want to fire the AsyncTask in the onCreate() method of your Activity, showing the ProgressDialog in the onPreExecute() method and then showing your information and hiding your ProgressDialog in the onPostExecute.
It's pretty much impossible to eliminate this lag you're talking about. So you better just handle it appropriately.
Hope this helps answers your question.

ListFragment with a Loader and an EndlessCursorAdapter - Nightmare

I will start with what I am trying to accomplish.
I have a ListFragment, with LoaderCallbacks associated to retrieve data from a DB. The data is downloaded using an AsyncTask, and inserted into the DB. When the user gets to the bottom of the list, using the CWAC-Endless widget the AsyncTask is kicked off and downloads more data.
I am facing a couple of issues here, and I have tried to sort this out over many a night, and I have decided to come here to ask for help.
The first issue is configChanges. When the user rotates the device, the Activity is destroyed, and then recreates all of the Fragments. I know I can use setRetainInstance to true, but this does not help as the AsyncTask is still running when the Activity gets torn down!
The second issue is to do with the Loader. If data is downloaded, and the AsyncTask completes fine, then the items appears in the List fine. Lets say there are 20 items in the DB. When the user rotates the device, and the Fragment is recreated, the Loader needs to be associated again. When this happens, the data is not loaded into the list straight away, and instead the AsyncTask for the download is kicked off because the CWAC-Endless adapter thinks its at the last item in the list!
Both of these issues have exhausted me. I need a fresh look on this, as im getting no where.
Any suggestions will do, and I can post up source code if needed.
EDIT
Ok here are a few more details to help with some suggestions.
I am downloading data from the internet, which will only return a set number of items at a time. I then have to request more data when I want it (pagination).
I decided to use a database, as the new Loader functionality makes it so simple to make sure the data is loaded efficiently and consistant, without any threading issues.
If it would make sense to ditch the Loader approach, and use a standard Adapter to render the data, I am more than happy to ditch this approach and use that. I just wanted to see if someone could offer an insight into why this solution is so difficult.
Thanks,
Adam
When the user gets to the bottom of the list, using the CWAC-Endless widget the AsyncTask is kicked off and downloads more data.
FWIW, I have not tried EndlessAdapter with this combination of stuff (cursors, loaders, and AsyncTask). In particular, quoting the docs:
Note that this has been tested with ArrayAdapter extensively but may not work with other adapter types
I am not even quite certain what the use case would be for an EndlessAdapter applied to a local database. If you have a crazy long list (e.g., thousands of rows), the answer isn't "load it progressively" but "provide a different UX to avoid the long list". For shorter lists, just load the whole thing and be done with it. EndlessAdapter is for cases where the loading is expensive (e.g., Internet access).
That being said, I will add "play with EndlessAdapter and Loader" to my to-do list.
I know I can use setRetainInstance to true, but this does not help as the AsyncTask is still running when the Activity gets torn down!
So? onPostExecute() will not be invoked until the new activity has gotten through onCreate(). Moreover, in a fragment-based model, your task should be talking to the fragment, and if that fragment is retained via setRetainInstance(true), it's the same fragment instance in both the old and the new activity.
When this happens, the data is not loaded into the list straight away
It should be loaded in fairly quickly, though asynchronously. Moreover, I don't see why this is any different from when the activity is created in the first place.
and instead the AsyncTask for the download is kicked off because the CWAC-Endless adapter thinks its at the last item in the list
You should not be creating the EndlessAdapter until after you have data.

Categories

Resources