I have an sqlite db with data I want to load async to a ListView.
I know that Loaders enable easy async data fetching + getting notified on data changed, but from what I see, Loaders work with ContentProviders.
Since in the documentation, it says that
A content provider is only required if you need to share data between multiple applications
I find it weird that using Loaders require a ContentProvider.
I found this thread where it says in one of the answer's comments that
... taking this I just feel I should implement a content provider even so it seems like a overkill for any small database i might want to list on the display ...
Is this the recommended course on action? Is there an alternative?
CursorLoader is designed to work with a content provider, but you can implement your custom Loader to work directly with the database, without implementing a content provider.
take a look -->
Android Custom Loader to Load Data Directly from SQLite Database
Related
What is the best way to use the ContentProvider to query data from my database?
I was told to never perform database functions on the UI Thread.
Is there a special loader to use when I want to perform getContentResolver.query(...)?
I assume from 'special loader' that you're using a Loader? From what I gather, the Loader construct was written with ContentProvider in mind (sort of). I gather that from talking with Google engineers.
Loaders in general are designed to load data in a background thread, so if you use them as directed, you'll be good.
Read about CursorLoader, which is what you want
http://developer.android.com/guide/components/loaders.html
To add my own 2 cents, if you're not sharing data outside of your app, ContentProvider is just extra work and code, but saying that makes ContentProvider fans upset, so feel free to ignore me.
In my android app i am performing sql data extensively where i need to download the data from server , store it into database and populating it on the ListView.
moreover, i need to perform the database search and filter the data in a ListView too.
so far in my past projects i have used simple method to manipulate database like manually opening & closing database , getting data from database using cursor and storing it in a array list and populating over ListView.
after exploring i came across the ContentResolver and LoaderManager and tried few samples too but i am not able to decide what to use where i need to perform more database operation with search in a ListView.
I would even love to know in which scenario what approach is preferable.
i am waiting for commonsware comments too ;)
ContentResolver/ContentProvider is meant for providing data to other applications. If you aren't going to do that, then using it is clunky and overkill. It really doesn't provide any value, and even Google's own docs suggest not using it for inside of your app.
LoaderManager- meh. The idea of a Loader is useful, and you're probably already using it- a loader is just the idea of reading large amounts of data from your DB on an AsyncTask. LoaderManager will provide some efficiency gains if you're being restarted due to configuration changes, but there's other ways to achieve them. It isn't a bad thing to use, but it will save you minimal to no work- you still have to write a custom CursorLoader to make your db call, and you'll have some code to manage the loader manager. You aren't wrong to use it, I'm just not convinced of its value.
I'm new to Android and have successfully implemented an ArrayAdapter to display a list of simple objects in a ListView. I have also created a class that extends SQLiteOpenHelper and I'd like to use this to display a list of rows from the database in the ListView.
From what I can tell, it seems like I should be using a Loader to asynchronously query the data, and act as a middle man between my data and the UI.
The Loader and CursorLoader documentation only refers to how to achieve this when querying a ContentProvider. This led me to think that the best approach may be to create a ContentProvider which provides a structured interface to my database - but the Android documentation on creating a ContentProvider states:
You don't need a provider to use an SQLite database if the use is
entirely within your own application.
Are there any particular reasons why I shouldn't write a ContentProvider? Unless I'm missing something it seems like this would provide a good abstraction for the data layer and mean I can have all the benefits of using a CursorLoader when consuming it.
In my case the database is only for use by my application - so what alternatives are there and are there any good tutorials which show the process start to finish?
Thanks!
I have to show the contents of a SQLite database in a ListView, and seeking the web I have found 2 options:
Using SQLiteCursorLoader, or
Implementing a Content Provider like here
Android Dev docs say a content provider is not needed to access a database, and it should be use to share data with other apps (what I do not need). What do you think is better in terms of efficiency, error-prone and simplicity?
Thank you guys!
Obviously sharing data is the most frequent reason people put for using a content provider.
There have been some bugs in sqlite and multiple users, although not absolute usually a content provider is in a single thread and can solve this issue and yes this is when your sharing data between apps.
A content provider can give you a level of abstraction and possibly have less code maintenance, especially with internal database structure changes.
It allows you to perform asynchronous queries with a CursorLoader, off loading your UI Activities, which is the design recommendation.
In conjunction with a database helper, it makes it easier to get your table and column names correct and narrows down where you have to look and maintain code.
The use of a database helper or contract between your application and content provider can provide some security, as you provide the methods to your and any other application on how the data get updated.
This can also give you some better data integrity, dependent on how complex your database structure is. It leaves the guess work out of was I supposed to update Table A first and then Table B or the other way around.
It can help with table joins and views so you only have to figure that out once and represent them as a URI.
You can created a URI to handle a raw query inside of a content provider to supply results, that otherwise might have been hard to write with the normal URI structure as it's presented in most tutorials. This is also useful if you have to write a correlated query.
I'm having a hard time to optimize backwards compatibility, complexity and best practice for SQLite database handling on Android. I found two not deprecated ways to manage SQLite databases and cursors:
Directly through android.database.sqlite
ContentProvider, CursorLoader and LoaderManager
I'm trying to design the database implementation future proof. This means I would like to implement a best practice promoted by Google. I found a tutorial on implementing ContentProvider and LoaderManager.
If I follow Lars Vogels proposals, my code is blown up with duplications and unnecessary complexity. It does make sense for some tables in my database. But it would make no sense to implement this for a mapping table with three fields (for example). Furthermore I'm having problems with ActionbarSherlock and the Callback Interface of LoaderManager (there's a solution but it would double my data handling classes).
Direct handling of database and cursors via android.database.sqlite is provoking problems with resource management (close your cursors!) and makes me responsible for task handling.
My Questions:
How are you handling SQLite databases on Android?
When do you go the extra mile and implement ContentProvider and LoaderManager?
How do you stay backwards compatible?
My current approach:
I created a class that separates database I/O (via android.database.sqlite) from activities. All methods open and close the cursors they use during their execution (outside of my activities) and return the objects or the data as needed (instead of a cursor). I/O operations are performed in AsyncTasks. This approach seems very deprecated.
I recently had the same plain sqllite / content provider dilemma, and it looks like content provider are the most common approach to solve the problem.
Even if the official doc states that
You don't need to develop your own provider if you don't intend to share your data with other applications
they added the option to have unexported content providers using
android:exported="false"
All the books I read, including Reto Meier's Professional Android Development 4, suggest using content providers.
Moreover, at the cost of a lot of boilerplate code, you can forget about multithreading and open cursor issues.
Anyway, I have to say that the biggest advantage you get from the content provider / cursor loader combo is that your loader is automatically notified whenever the underlying data changes.
If you use plain sqllite you need to implement some way to get the client classes notified whenever the data changes in background. For example, I used broadcasts to notify any activity that the tables where updated inside an intentservice.
Finally, I was a bit disappointed by all the code duplication that you are ranting about, and I decided to write a python script to generate the content provider in my place using just a description of the data model. You probably have to modify the generated class (or better, to extend it), but I think it saves quite a lot of time. You can find it here
Conclusion:
if you want to export your data to other apps (not so common), you need to go for content provider
if you want to observe the data / update the ui because your dataset might be changed in background, content provider + loader is extremely powerful
if you have a preloaded data set, and maybe you update it in the same activity that display the data, or you need to perform simple operations with your tables, maybe a sqllite helper class is just enough