I am using a FragmentActivity to display information from my own ContentProvider which is loaded with a CursorLoader. That ContentProvider delivers a phone number and I would like to have the name and image of that contact if available.
In the first approach I queried the ContactsContract in the CursorAdapter but that isn't the best solution as it makes the scrolling laggy even on fast devices.
I thought and searched about my problem and created 3 ways:
A left join with two ContentProviders but I found nothing about that.
Creating a custom Loader class like here.
A service wich adds the information from ContactsContract to my own ContentProvider so I only have to query one provider.
Let's discuss that. :D
Kind Regards,
k.j.
I figured out that what I was trying was not the best idea.
Now I will use a small AsyncTask when I start my app that updates my internal Database with information from ContactsContract. With that method I can use my own ContentProvider with all needed information in a very simple way. :-)
Related
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 am working on an application whose purpose is to display a listview whose content will depend on which button the user clicks, and whose data come from a sql databse. It means my database will be using a "readable" attribute only, no need to change information from the database.
So, to learn how to do it, I am reading and doing lot of tutorials and i feel a bit lost about what is really required and what is optional in the design of the application.
Here is why. I have learned that to do so, my app will need:
- a ----Helper class (extending SQLiteOpenHelper)
- a ----Adapter class (to define my methods and queries for the database)
- a ----Table class (one class for each table of my database)
- my MainActivity (in my case, extending ListActivities)
And then, i found out that to do so I also need :
- CursorLoader
- ContentProvider
- fillData()
Every time I try to learn more, I find out about more and more classes or methods to use, it seems endless and I don't know if I really need to have that many classes for my application.
If someone can tell me if it seems right to have that many things, thanks in advance!
First of all, you need to have a high level overview of what exactly you are going to do with the database and how. And, what you have figured out is almost correct.
Basic Steps for any DB app in android are :
You will require Helper class, using which you can create or upgrade database along with tables.
Once you have database ready, there is a need for the class which will contain the data that you need to save in the database.
And lastly, there will be a class which will fire queries and retrieve data from database.
Till here, all backend functions are complete. Now you need to display the data that you have retrieved from db. For which, you use another class(in your class, one which extends ListActivity).
Don't get overwhelmed by number of classes, all the functionalities are kept in separate classes just to avoid cluttered code. But the basic steps remain same !
And then, i found out that to do so I also need :
- CursorLoader
- ContentProvider
- fillData()
Yes, these are different things that you could use to perform required function, like ContentProvider is used if you want to share data with other applications. So just figure out if you want to do that, and then only move ahead. Else the basic steps are enough.
Hope this helps!
You may refer a very nice tutorial on this : http://www.vogella.com/articles/AndroidSQLite/article.html
Me and my Android team have a problem. We have an app that present the user's contact book, with extended information.
Current setup
Our app reads the Contacts Provider of the Android OS. Sends this information to our Server that calculates a couple of necessary fields for us. This information is later fetched by our app and we save this information in an SQLite database. What we end up with in our database is two tables. One with all Numbers and all the extra information that the server calculated for us. The other table is one with all Contacts (one contact can have multiple numbers). This Contacts table was created only for performance; we can have a Cursor selecting all rows in this Contacts table in our CursorAdapter when presenting the contact book for the user.
Hence, when presenting the contact book to the user, we only need to read from our own SQLite database and only one table (e.g. no JOINs).
The main problem
There is a lot of syncing going on. Since, data is duplicated, we need to check for adds/changes/removes and need to sync all the f-ing time. Moreover, when we now are about to change a particular thing in our presentation layer, we need to change our Contacts table to include this particular information.
Priority for us
1st: Performance when presenting the contact book to the user.
2nd: Code maintainability.
Hence, do not comment "Do not duplicate data--it's the root of all problems". It is more important to us that the user does not have performance issues than if we as developers have to spend some extra time writing good synchronization algorithms.
Solutions?
I don't know why, but I've always thought that a CursorAdapter (reading all rows from one table) is performing much better than an ArrayAdapter with a List of objects (held in memory). Anyone know if this is true? Because one solution which will help us at least half the way is to, on start up, join the Contacts Provider (native contact book) and our extended information, save this in a List in memory and present this with an ArrayAdapter.
Creating your own Content Providers? I know little about creating your own content provider. Anyone tried to create a content provider that extend the information of the native contact book and join these. Maybe with the implementation of this interface: ContactsContract.DataColumnsWithJoins? Anyone tried anything similar? How's the performance when presenting this information in a CursorAdapter?
Please ask for any more information I might have forgot and I will update the question!
Thanks a lot in advance for all helpful tips and solutions!
I have come to conclusion (working on my app JReader which relies on fast DB operations a lot) that SQLite in Android is pretty quick as in other platforms but there are some Android specific issues.
Some advises regarding database performance and the questions you have asked:
Content providers are mostly useless if you are not planning sharing your data through them. But they provide at least 2 advantages. First you get data change notifications and you cursor gets updated automatically, and the second and important one: CursorLoaders require a Content provider, and if the performance matters to you, I would strongly suggest using them for loading your cursor;
Accessing Collections is much faster that accessing database, but it is a double work, since you have to persist the data anyway, and DB access is quite fast even for fetching data for a super-fast scrolling list and especially from a single table, it shouldn't be a problem;
Design your DB properly (with JOINS, indexes, etc) :) BUT DO NOT USE JOIN QUERIES IN CURSOR QUERIES! I have had lots of performance issues with that on multiple Android platforms (including 4.0+), not always though. The way I access joint tables is by simply getting foreign key first and then querying child table.
In my experience, I've had the situations when the DB performance was very poor, but in the end I have always managed to tweak the code and as a result would gain 10-100 fold performance increase. So keep profiling you DB code, and you will definitely achieve the desired performance.
Dan's 2nd comment is true .. Android Uses Cursor Window below the screens to Cache data from the Cursor (approx 1M ) . see Android docs on Cursor Window, Which is how the Cursor Adapter is quicker .
If you do not prefer joining two tables seperately you could consider a CursorJoiner which is faster, This can go to your custom contentProvider where one of the provider is pointing to the Contacts and returns a Cursor , similarly the second one points to your own table and returns a cursor . The cursorjoiner can join both these cursors .
(Though it is a complicated process )
I'm new to android development and I've got a little stuck with the new API, I can't seem to find a tutorial to help.
I've got a database with a SQLOpenHelper and a Database adapter that I've seen used in many examples, such as this. I want to hook up the data into a list, so have created a ListFragment. The tutorials that I've seen use the startManagingCursor(c) method in Activity, however the documentation says that this is depreciated and to use CursorLoader.
To use the CursorLoader it looks like I need a uri, which implies I need a content provider. I don't need a content provider for my app, so I'm not sure how to implement this or what is the correct/ recommended way.
A shove in the right direction would be great!
Some points that I need to add here
Use CursorLoader instead of startManagingCursor. It is easy to use and more safe
Check The Problem with "Managed Cursors", explain that correctly
Definitely the best approach is to use content provider in front of your database to get the uri
It is very simple to implement Content provider with your db, check Simple Content Provider for db operations
From what I've read and understood, the Android team encourages the use of a ContentProvider that sits in front of your database. As you can see with CursorLoader, the Android API is also encouraging this usage pattern.
Letting aside discussions if this is the best approach for small apps, I think you should not fight the API and go with a ContentProvider. CursorLoader handles a lot of stuff for you and I find it works really well.
Yes, use ContentProvider, that's Google teams encounge to do. Remember the three layers in database book:storage, logic,application. Contentprovider act as the logic.