I'm having issues with multithreading in my application. I know there are many posts on Threads/AsyncTasks/etc, but none seem to address my specific problem.
Basically, I get a query string in my search Activity, then send it to my results Activity, where the string is used as a SQL query, the results are returned as an array of JSON objects, then I display these objects in a ListView (which is part of the results Activity). All of my SQL connection and retrieval is done in a separate class that I call at the start of the results Activity.
MySQLRetrieve data = new MySQLRetrieve();
ArrayList<Tile> tiles = data.getResults(nameValuePairs, isLocationSearch);
The above code is how I get the SQL response and convert into an ArrayList, which I then use the populate my ListView with. getResults() takes care of all of this.
I already have separate threads working to download images into the ListView, but what I can't get to work is getting the SQL query and result to run in it's own Thread. What I want to achieve is this:
User enters search query in search Activity.
Intent is sent to results Activity, and it starts immediately.
ProgressDialog (just the animated spinner thing, not a loading bar) displays while the SQL query is taking place.
ListView populates with objects from the JSON array, lazy loading images as they come.
I have steps 1,2, and 4 working well, but 3 is the problem. I've looked up AsyncTasks, which seem to be the answer, but I just can't get them to work. Does anyone have a solution to this problem? I need to do this, so when starting the results Activity, the UI changes immediately to the results Activity and doesn't have to wait until the SQL response is returned.
And yes, I've already read the painless-threading post.
Thank you.
I would recommend against creating that ArrayList<Tile> to reduce memory consumption (and code size) and instead directly bind the SQLite Cursor to the ListView using a CursorAdapter.
That alone might just increase the performance enough that you don't need to do any async loading.
If you still want async loading, check out the LoaderManager framework (available since Android 3.0/ API level 11, with Android support package down to 1.6/4) which will automagically do asynchronous loading of your Cursor -- either using the built-in CursorLoader (if you happen to have a ContentProvider), or the SimpleCursorLoader created by a fellow SO user (if you don't).
Related
As far as I know, Android listview shows the data virtualized (meaning it loads only the visible ones), so it is fast as it can be.
I have lots of data to get from the database (around 2000 but with lots of data in the fields), and I use ActiveAndroid in an AsyncTask to get them.
Unfortunately the AsyncTask with AA takes around 10-15 seconds to get the data so I see a progressbar during that time.
I get his by this code:
LocalDateTime start=new LocalDateTime();
LogCat("Start: "+start);
elements = new Select().from(Data.class)
.where("Data_Id=?", DataId).orderBy("Name ASC").execute();
LogCat("Elements: "+elements .size());
LocalDateTime end=new LocalDateTime();
LogCat("End: "+end);
LogCat("Time: "+(new Period(start,end).getSeconds()+" s"));
It would be good to accelerate the loading by somehow virtualizing the data retrieval.
I also use a search in the listview, that searches the whole list. So considering the would be also good.
What do you suggest? How should I proceed?
Pairing content provider and CursorLoader should solve your issue.
I'm working on an Android project I need to finish very fast.
One of the app's features is loading a SQLite database content and listing it in a ListView inside a ListActivity.
The database contains a few tables, among which 2 are very large.
Each item in the database has many columns, out of which I need to display at least 2 (Name, Price), although preferably is 3.
This might seem a pretty easy task, as all I need to do in this part of the app is read a database and list it. I did this without any problems, testing the app versus a small sample database.
In my FIRST version, I used a Cursor to get the query, then an ArrayAdapter as the list's adapter, and after the query I simply loop the cursor from start to end, and for each position I add the Cursor's content to the adapter.
The onItemClickListener queries the database again versus other parameters (basically I open categories) so it clears the adapter, then loops the Cursor and adds its content to the adapter all over again.
The app worked like a charm, but when I used a real-life, big database (>300MB) I suddenly got my app taking very long to display the contents, and sometimes even blocking.
So I did some research and started using a SimpleCursorAdapter that automatically links the contents of a Cursor to the ListView using the usual parameters (String[] from, int[] to etc., where I used android.R.layout.simple_list_item_2 and android.R.id.text1 and text2).
Problem is, is doesn't change much the time to load.
I've came across some suggested solutions on different web sites and tutorials, most of them using, in one way or another, the AsyncTask class. I tried implementing this manually myself but it's hard to keep track of multiple threads and I failed.
Tutorials keep telling how to do this with content providers, but I found nothing clear bout my specific situation: very big SQLite database -> read to ListView.
Now my head is filled in with notions like LoaderManager, LoaderAdapter etc, all mixed up and confused in my head.
Can anybody please provide me a complete, nice, clean solution to do this "simple" task?
Again: I want to read a BIG SQLiteDatabase and display it in a ListView. I want the app NOT to block.
I need a class that has a member function that takes as parameter a query and the ListActivity's context and takes itself care of displaying the result of the query in the view.
Please don't provide me abstract answers. I'm running out of time and I'm very confused right now and I need a clean complete solution.
You're my only hope.
If you query such large database it will take tym, you need to find a smart way,
Like limit you database query to get first 10 or 30 items and then maintain,once last item is reached query rest 30 items and bind them
Refer this tutorial, it will teach you how to add data dynamically in a list view
http://p-xr.com/android-tutorial-dynamicaly-load-more-items-to-the-listview-never-ending-list/
The above list has expired chk this
http://mobile.dzone.com/news/android-tutorial-dynamicaly
If you query large database it will take time to fetch data and show it on List View. So it is better to populate data at run time. You can use Lazy Adapter concept to load data . This link1 may be useful for You.
Thanks
you can also use :
public class TodosOverviewActivity extends ListActivity implements
LoaderManager.LoaderCallbacks<Cursor>
check this link for more details.
In my Android app, I am making a http request, getting some data, putting it in my local sqlite database & then populating a gridview using that data. I have the code working for an activity but I need to use fragment now to get this done as there are many similar pages to be shown. I read that using Loader is the best way to deal with data in a fragment.
I am not sure about:
Whether to use CursorLoader, Async taskLoader or SQLiteLoader(developed by commons guy).
In which of the loader functions (onCreateLoader(), onLoadFinished() etc.) do I put my code for making http request, populating the local database & getting the data displayed in a gridview in my fragment
I am also using a lazyload list to show images. How will that fit into the entire thing if I use loader
Can anybody help me with this one? Tried searching for good examples or tutorials but I haven't really found something that's really useful. So, please suggest any if you can. Thanks
Whether to use CursorLoader, Async taskLoader or
SQLiteLoader(developed by commons guy).
CursorLoader is for ContentProviders(which is not your case) and AsyncTaskLoader is the way to go. I haven't use the classes from Commonsware but if they allow overriding of some of their methods then I guess you can use it.
In which of the loader functions (onCreateLoader(), onLoadFinished()
etc.) do I put my code for making http request, populating the local
database & getting the data displayed in a gridview in my fragment
In none of those callbacks because they run(most likely) on the main UI and you must not do network operations in there. The Loader subclasses have the loadInBackground method which runs on a background thread. On this method the Loader queries for data and in which you could place your networks requests and database updating. But you would need to be very careful to not insert duplicate data in the database.
I am also using a lazyload list to show images. How will that fit into
the entire thing if I use loader
As I haven't seen your code, I don't think this two parts are connected. I'm guessing that you use the lazy image loading code directly in the GridView's adapter.
My advice is to not use Loaders for loading and inserting data because their purpose is to only load data on a background thread(having taking care of configuration changes). For your particular situation I would make my own AsyncTaskLoader(or use Commonsware's library) which queries the database for new data. I would then start a new AsyncTask to do the http request and to insert data in the database and then I would trigger a Loader restart in the onPostExecute method of the AsyncTask(with getLoaderManager().restartLoader...). Have a look at this similar question for some problems related to what you're trying to do.
I'm relatively new to Android and have the following question. I have a local DB on the device from which I want to display the content in an ActivityList. Let's say there is a table "person" on the DB containing general information like "name, surname etc."
Every row in the table should be displayed as an item within the ActivityList.
I know that there exists a sort of Adapter with which I can directly fill the ActivityList with my table data, but is this the way to do it?
Isn't it better to load all the data at startup and then hold them for the entire session and pass the data from one activity to another(or make them static..) if necessary, instead of loading the data every time I change to another Activity?
If I would have a normal Java application I would load the Data at startup and then just work with the loaded objects (at least for reasonable data sets).
Doesn't it make sense for an Android App too?
I will up-rate every answer that makes sense to me.
Thanks!
Slash
I would have a look at the ContentProvider.
You can use it to query your database and then show the content in the ListView using a CursorAdapter.
You need to use an Adapter if you want to work with ListView. So, that is a must. And you can set the Adapter data from your Activity.
As for the "sense" question, it probably makes sense. But as always it depends on a few things:
Will this data be used through out the application? Then it absolutely makes sense to load it once and use it everywhere. How you do that is up to your needs, static access or passing the data, all should work.
And DB access is always expensive. And if you have lots of rows, the loading process from the database can be extremely slow. So, again, load it once and use it everywhere is a good plan.
But be careful about blocking the UI thread when you load this data. You should never access DB from your UI thread. Instead use a worker thread or AsyncTask.
I have a following situation in my android app.
I have an app that fetches messages from inbox, sent items and drafts based on search keywords. I use to accomplish this by fetching cursors for each manually based on selection by user and then populating them in a custom data holder object. Filter those results based on given keywords and then manually render view with respective data.
Someone suggested that I should use a custom Cursor adapter to bind view and my cursor data. So I tried doing that. Now what I am doing is this:
Fetch individual cursors for inbox, sent items and drafts. Merge them into one using Merge cursor and then pass that back to my CursorAdapter implmentation.
Now where or how do I filter my cursor data based on keywords; because now binding will ensure that they are directly rendered to view on list. Also, some post fetching operation like fetching sender's contact pic and all will be something that I do not want to move to adapter. If I do all this processing in adapter; it'll be heavy and ugly.
How could I have designed it better such that it performs and the responsibilities are shared and distributed.
Any ideas will be helpful.
Using cursors and adapters does not work out well for the most part. Our experience as led down a different technique.
Your best bet is to "pump" the cursors in an AsyncTask into an ArrayList<data-holding object>, then you can do processing and then sort that list as necessary with Collections.sort() and the Comparator of your own construction, and then use ArrayAdapter to present the resulting list. This releases cursors ASAP and stays off the UI thread while doing it and you can sort however you feel like.
Remember always process in the background and avoid ANR!
We use this in all of our apps (14 on The Market) and it works like Butter.