while reading the documentation on Cursor here I read that cursor provides read/write access. I had gone through the API methods of Cursor but there is no setter method available to write into the Cursor. It would be of great help if you could provide me with code snippet. Thanks in advance
I think that's a bug in the documentation. You are quite right that there are no Cursor methods to modify the underlying data.
If you do try to modify the underlying data (by executing SQL statements, for example) while iterating over the data using a Cursor, bad things happen. If you need to make changes, you should keep a separate record of what you need to change whilst iterating with the Cursor, and then apply those changes separately once the Cursor is safely closed.
Related
When I use SQLite to bring my data and use cursor and adapters, should I use cursor Loaders??. Is this the best practice?. Im not quite clear when to use cursor loaders. Should I use it only if my app shares data with other apps?. My question comes because it have been really annoying for me using cursors + adapters + listView; sometimes the notifyDataSetChanged works, sometimes not, so it have been really tricky sometimes. I start reading about cursor loaders but Im not sure if this is a work around for this in particular or if I can use it as a work around.
Any clarification will be really appreciated!!
Thanks guys.
Use Loaders to ensure that all cursor operations are done asynchronously, thus eliminating the possibility of blocking the UI thread.
When using CursorAdapter donĀ“t use notifyDataSetChanged instead use:
db.updateData();
yourCursor = db.getData();
yourAdapter.changeCursor(yourCursor);
I am in a situation where I will probably need to manipulate two separate Cursor objects. I was hoping there was someway to create our own Cursor by combining two separate ones. But I am not sure if it is even allowed. Read somewhere you can't, but I wanted to devote a specific question to that so it is at least given some attention for others who have a similar situation.
I was hoping there was someway to create our own Cursor by combining two separate ones
Have you tried MergeCursor? Quoting the documentation:
A convience class that lets you present an array of Cursors as a single linear Cursor. The schema of the cursors presented is entirely up to the creator of the MergeCursor, and may be different if that is desired. Calls to getColumns, getColumnIndex, etc will return the value for the row that the MergeCursor is currently pointing at.
Also, if your objective is to display both Cursors in some form of AdapterView, you could use my MergeAdapter and concatenate things at the Adapter level
Even if you found a solution for your concrete use case, i would still like to answer your main question.
Yes it's possible to implement your own cursors.
Cursor is a public interface and can be implemented by everybody.
It has, however, a large amount of methods that need to be implemented.
Using AbstractCursor or AbstractWindowedCursor as base class can help to reduce the overhead.
The available concrete implementations can be extended, too.
CrossProcessCursor, CrossProcessCursorWrapper, CursorWrapper, MatrixCursor, MergeCursor, MockCursor, SQLiteCursor
I am new to android development and I've hit a hurdle when trying to load SQLite data to populate a ListFragment. In previous versions of android one made a new instance of the cursor class, made an SQLite query to place the cursor in the appropriate position, called startManagingCursor, made a new SimpleCursorAdapter and finally called setListAdapter. Pretty darn simple (too bad about the UI thread)!
Now almost all of these methods are deprecated and I have no idea how to populate my poor ListView. The documentation says I should use CursorLoader but here on StackOverflow people advise against using it for SQLite queries. How do I tell my cursor to populate the ListView?
Thanks a lot in advance!
You need to convert you DbAdapter into a Content Provider if you want to use CursorLoaders. and put android:exported= false as a property of your content provider so that it is private. Android team is favoring this approach as they say Content Provider is better suited to handle logic. That is why they are bent on deprecating our old ways( was hard on me too). But I have changed my dbadapters to content providers and now gleefully using cursor loaders( they are too cool not to be used). Try it, generally you will do fine with some more boilerplate code of Content Providers in adition to that of DBadapter and sqliteHelper. GO for it!
I have a ListView bound to a SimpleCursorAdapter, and I want it to refresh when I modify the database (by inserting, updating or deleting rows). cursor.notifyDataSetChanged() has no effect (it's called on the UI thread) and ListView.removeViewAt(int) throws an UnsupportedOperationException.
What am I supposed to do on Android to get such a basic behavior?
Note that the database is correctly affected and the modification is shown when I restart the activity. But restarting the activity is not an option here, and changing the ListView adapter is the last resource here, since it's a hack and can't guarantee a smooth transition
DISCLAIMER
Quite basic question, asked millions of times and answered zero.
Please, do not answer if you have never done this in your code, don't ask for mine, and don't bother with try this or try that. Only answer if you know how it's done
From API >= 11 the way to do this is using a CursorLoader, this is also included in the Android Compatibility Library, so you can also use this if you are targeting a previous Android version. CursorLoader will make the query in a background thread and return you the cursor. You will need to implement a ContentProvider. You can read the documentation to get an idea of how to use it. Basically you init a loader and then you restart it when you know data has changed. In the callback you just swap the cursor of your adapter.
Or you can just use requery() on the Cursor. The adapter will get automatically notified of the changes. This method is deprecated now and, of course, it's not the recommended way.
Currently I am displaying data from an SQLite database in a multiple-column ListView. However, I would like to use calculated columns in my data involving more complicated mathematical functions than those available in SQLite queries.
In this thread the following advice was given for this sort of situation:
... if you are putting the Cursor into some sort of CursorAdapter, you could:
(1) convert the Cursor into an ArrayList, where Position is some Java class you define with your data
(2) close the Cursor, to release the RAM it takes up
(3) sort the ArrayList using Arrays.sort()
(4) wrap the ArrayList in an ArrayAdapter and use that where you had been using your CursorAdapter
My problem is that I get stuck at step (4), because ArrayAdapter seems to be less flexible than SimpleCursorAdapter. I have been using SimpleCursorAdapter to define the mapping from the database columns to the ListView, but there seems to be no equivalent method defined for an ArrayAdapter.
I have seen references on the web to an Android object called ArrayListCursor. This sounds as if it would do just what I want, but it does not appear in the current Android Reference and it doesn't seem to be recognised by Eclipse.
If ArrayListCursor has been superseded what has replaced it?
I do not remember ever seeing an ArrayListCursor. There is a MatrixCursor, which allows you to build up a Cursor from rows and cells. You can also implement AbstractCursor to do whatever you want.
Whatever you do, try to minimize the data copying you do, which is why I would recommend either:
Creating your own AbstractCursor subclass that wraps your database Cursor and blends in the calculated values
Just leave your original Cursor alone and use a CursorAdapter subclass to blend in your calculated values