Is it necessary to do SQLite local querys in an Asyntask? - android

I have a doubt... I want to execute this code, but I don't know if it's better to do it in an Asynctask or it isn't necessary and I can execute it in the main function.. What do you think?
The SQLite Database is local, so the acces is so fast.. Thank you!
/*Here I create an object of SQLiteHelper Class*/
SQLiteHelper bbDD;
bbDD = new SQLiteHelper(getActivity());
/* Calling this method I open the database connection */
bbDD.open();
/* This method returns me an ArrayList, doing a SELECT in the SQLite Local Database*/
arrayList = bbDD.selectAll();
/* Here I Close the database connection */
bbDD.close();

Today's devices are fast enough to handle SQLite query inside main UI thread, but when you try to query big size of data inside SQLite (for example if you have more than hundred rows of data inside that database (Especially if row contains base64 encoded image strings)) user can see some UI lag, that's why query in Asynctask makes UI faster - without lags. If you don't have big data inside SQLite, there is no need to use AsyncTask for query.

No dude there is no need to write SQLite local querys in an Asyntask.

The answer to your question depend on the size of your database.
I have experienced to select hundreds of rows, with lot of columns on SQLite. It does not make the apps very lag, but it does make the apps a little bit lag (and my client can feel this). So, i moved the select operation to the onBackground in the Async class, and the apps run flawlessly again.
If you only have a little data, theres no need to put it on the background.

Related

Android: efficiency of CursorLoader-swapCursor vs ArrayList-notifyDataSetChanged?

I have a list which usually contains < 100 entries. Sometimes 200-1000 entries. Occasionally it can contain many more such as 20000 entries.
Data is queried from a few SQLiteDatabase tables.
I load and display the data in a ListView.
I do various reads/writes in other app logic such as in a service etc.
I do operations such as: move some items around, to beginning or end of the list, modify their content, delete them, add new ones etc. - and save changes in the DB.
For the ListView I call mAdapter.notifyDataSetChanged().
I consider implementing a Loader (SQLite query loader) to use Loaders. The loader will observe data changes, re-run the query and I would use mAdaptor.swapCursor() to use the new Cursor.
My question is: while both methods would be asynchronous, which one of the above would be more efficient? (shorter loading time etc)?
It's my own question too, but I think based on my information that:
Querying the database reads from file-system which is much slower than RAM (You can visit this link)
Adapter has some more efficient methods for notifying dataset changes like notifyItemRangeIserted() and so, and the ArrayList will reside in RAM as your application resides.
So I conclude that caching data in memory will be faster but you absolutely should be careful about heap size and memory leak!

Android: multiple threads writing on SQLite database

In the onCreate() method of my main activity I call the constructor of my dbManager, I call the open function that creates an instance of a SQLiteOpenHelper and than I call the getWritableDatabase() on it.
Within the UIThread I add records to the database and save those records to an ArrayList. Two other threads check the ArrayList do stuff and than update the list and the database.
Now I want to add a button in the UI to delete both database and list records using an AsyncTask.
I've read that the SqliteOpenHelper object holds on one database connection. So if there is one helper instance there is only one db connection. This connection could be used from multiple threads and the SqliteDatabase object uses java locks to keep access serialize. So If I have multiple threads writing on the database, a thread will wait until the previous one has finished his operation?
Adding the new functionality (remove all) could create problems, because I have to avoid that one of the two threads may try to edit a record that no longer exists. How can I achieve my goal? Thanks.
The databese:
As long as you use only one helper, you are thread safe without a need to do anything.
In a multi threaded app, you'll need synchronized only on the creation of the helper.
You can use transacion if you want to define a critical section (more than one atomic operation).
Wrap each call with getWritableDatabase() and close(false):
public void doSomething() {
SQLiteDatabase tdb = getWritableDatabase();
dbInstance.writeSomething(tdb, 1);
close(false);
}
In this way I have multiple threads reading and writing to the database without any problem.
You app logic:
Use memory to keep track of object state, and use the database as storage only. So if one thread deletes rows from the database - you can immediately update your objects in memory, and handle your ui accordingly.
If your data is very large, than you can keep in memory only a SparseArray of dirty rows id.
It may be useful to synchronize some operations here.
So If I have multiple threads writing on the database, a thread will
wait until the previous one has finished his operation?
Doesn't need to be so. See this for more details. Anyway, this is up to the DB engine and should be transparent.
Adding the new functionality (remove all) could create problems,
because I have to avoid that one of the two threads may try to edit a
record that no longer exists. How can I achieve my goal?
Have only one thread update the DB. Other threads only modify the ArrayList -also watch out because ArrayList is not thread-safe, consider using Collections#synchronizedList().

Loading a BIG SQLiteDatabase in a ListActivity

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.

Downloading data in separate thread before initializing a ListView

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).

How to load data to make them visible in an ActivityList?

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.

Categories

Resources