I have a quick performance question; I have a ListView adapter which populates the listview and I open my sqlite database and close it at the end of populating the view and I populate some information about the list row from the SQLite database. I have noticed a serious performance hit with doing this mainly when scrolling which makes sense. I'm wondering how I can improve the performance of scrolling. I query the database about 3 times.
Database db = new Database(context);
db.open();
viewHolder.first.setText(db.queryFirst());
viewHolder.second.setText(db.querySecond());
viewHolder.third.setText(db.queryThird());
db.close();
Should I keep a reference to DB as an instance variable and just open and close when I query or how should I go about this?
I'm wondering how I can improve the performance of scrolling. I query the database about 3 times.
I recommend querying the database once for the whole adapter. Currently you are sending three queries for each row and none of them are cached. Reading from the drive is a slow process, Cursors are designed to fetch a large amount of data very efficiently and CursorAdapters are designed to use the least resources possible. Using one Cursor and a CursorAdapter will allow users to scroll without noticing any performance loss.
There is also a library called ORMLite which allows you to manipulate database quite easily and you get back a list, which means you load the array first and you don't have any scrolling performance issue. This in combination with lazy loading sections of the database will allow you to seamlessly increase the performance of the scroll.
Related
Suppose, In my app I have a sqlite table that can contain at most 20 row. Each row has 2 column(id, name). Where I frequently need to search by Id to get Name. For this frequent need I have two solution:
Solution 1: Get rows in a arraylist<model> and then find name from array.
Solution 2: Every time search on sqlite table.
Now please give your opinion which one is better?
Remember again, I need this search in my recycleView item, so it call so frequently.
Thanks
I don't really get what is your real intent, but if your task is to search by id often, I would use
LongSparseArray<String> idsToNames; // or LongSparseArray<Model>
Which will map primitive long to Strings in a more memory-efficient way than Map and will have a better performance than ArrayList when searching.
The advantage over querying SQLite here is that you can do it in a blocking manner instead of having to query database on a background thread every time the lookup runs.
The disadvantage is that whenever data changes in SQLite, you will have to rebuild your idsToNames map. Also, if the number of entries in SQLite will eventually grow, you will end up in a large collection. So I would recommend this approach only if the updates to the database during this session will not happen, and if the data size is always predictable or fixed.
In most of the Android sample codes, populating a ListView from SQLite database is done in two ways,
Prefetch data to List - Execute query, create Model objects for each row then add it to a List and close the Cursor, then populate ListView with List.
Without List and Model objects - Execute query and populate ListView by following the Cursor using moveToFirst, moveToLast, move, as required.
Now I want to know, which of the above method is more memory efficient, in Android ?
The Cursor approach is more memory efficient:
Suppose you have 1000 entries in your database and you have a ListView which can show 10 entries at the same time. If you create a list at first, you'll have to create 1000 model objects (each of which in turn consists of several objects depending on the number of columns of your table) and the listview creates additional 10 views (actually some more, depending on the layout of the list) for displaying the 10 items. Now when the user scrolls the list, in your Adapter you end up copying data from your model objects to the list item views currently in view.
On the other hand, if you use a CursorAdapter, whenever you have to fill a list item with data, you are provided with the Cursor holding exactly the data for that row and you can simply pick the data of the columns you actually need to be displayed in the list item. No need for creating the 1000 model objects.
From a code readability perspective, a model approach would be better because working with Cursors is quite low level, you'll need to know the names of the columns in the database and so on.
I think you need to use Service or at least Thread/Async so your UI thread will not be blocked. Service is better because people can go to other apps while downloading. You can use BroadcastReceiver to communicate with your running Service.
I'm currently working on a SQLite code base with a table that can hold a large amount of records. It has so many records that using a LoaderManager to asynchronously retrieve Cursor objects is becoming slow to display them in a ListView with a CursorAdapter.
If there is one row change in the table being queried, the LoaderManager is notified, and a new Cursor is retrieved. But, this seems inefficient because the Cursor queries for all the rows in the table for the ListView. The GUI isn't being blocked because the Cursor loading is being done in another thread, the problem is that the retrieval of the table rows can take a while. 5-10 seconds can pass on some slower phones before the new record information is displayed.
I'm trying to find a way to efficiently retrieve row changes to update the ListViews's rows without reloading everything.
I've looked into rewriting my code as a internal ContentProvider (hiding SQLiteDatabase) because I've seen it can be used with the app's ContentResolver to send out individual row change notifications via notifyChange().
If I switch to a ContentProvider, will it be as efficient as I've assumed? Upon individual record changes, can the ContentProvider send out events that will allow a ListView to reload only the row change information, and not require a complete requery of all the table information?
when implementing query() method of your ContentProvider return a custom. AbstractWindowedCursor, that way even if the final data set is huge you just fill the small window
I'm a new Android Developer and seem to have gotten in a little over my head. I am trying to make a listView update when I add more content to the list.
The ListView is based off of a SQLite database. I was able to get the ListView to be based on the SQLite database by making a ContentProvider for the SQLite database (which was suggested here). Now my issue is that I want to update the SQLite database and have it reflected on the ListView. I am using a loader and according to this if I implemented the loader right it will monitor the data.
I tried updating the SQLite database directly but, that didn't cause the ListView to update without closing and reopening. My instinct from there is that I should implement the insert method in my contentProvider. I did a very simple implementation:
#Override
public Uri insert(Uri uri, ContentValues contentValues) {
return ContentUris.withAppendedId(uri, mCollectionDB.insertCollection(contentValues));
}
Unfortunately, the result of this is my app crashes with a "java.lang.NullPointerException". This is especially confusing as using the exact same contentValues to make the .insertCollection call from my MainActivity works without issue.
The issue I'm really interested in is how to get my listView to update when I insert data into my SQLite database. If inserting into the ContentProvider is irrelevant then please ignore that. I'm not really sure where I went wrong so I'm not sure what other code may be useful, but I'm happy to edit in more code if it'll help.
You can check loader concept.
You can start with
http://www.vogella.com/articles/AndroidSQLite/article.html#todo
Following are other 2 good tutorials
http://mobile.tutsplus.com/tutorials/android/android-sdk_content-providers/
http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/
Hey here is one example to insert data into sqlite database and display it in list view.
Have a look at it
The idea is simple insert data into database and on click of view button initialize List view with arraylist that contains data already inserted.
You can ask if you have any further queries.
I need to populate ListView with List of objects returned from my Dao object.
The items get returned after 3 seconds, obviously to much time for the user to wait...
I'm using BaseAdapter as the ListView adapter.
2 questions:
How can get rid of the 3 seconds waiting time? Should I just retrieve the entire list of objects in a seperate worker Thread and display dialog in the meanwhile? Is there any mechanism that allows me to get the first, let's say... 20 records, display them and fetch the rest of the records while the user scrolls down the list?
If I would use cursors, rather than ORMLite, the list would then query the DB as the user scrolls down the list, releasing the objects of the hidden cells and the cells themselves, and not keeping all the objects of the cursor in the memory. How can I achieve this behavior with ORMLite?
I hope I was clear enough, despite the bad English ;)
Thanks.
You might want to load the data in an AsyncTask, and display a ProgressDialog while it loads. Lot of Android apps do this.
Cannot OrmLite return a DataProvider instead of the while list? (I too wanted to look into ORM on Android but the management decided against it "Its slow", but I still badly want it)