Reputation: 44090
I have created a ContentProvider for my main Sqlite table, pretty much following NotePad example from SDK (although I am not sure whether I will ever be exposing my data to other apps). However, I need to create lots of other, non-trivial queries on that and other tables and views. A good example would be queries to extract some statistics from the base data, averages, totals etc.
So what's the best place for this code in an Android project? How it should be related and connected to the Uri-based data access exposed by a Provider? Any good examples out there?
Upvotes: 3
Views: 2687
Reputation: 6592
From the point of view of maintainabillty I think that the provider model is the cleanest way to abstract the data access code. And from experience having worked on a large application, eventually the application will grow to the point where some data must be exposed via the provider model (e.g. introducing services to the application). That said exposing many different views of your data can be a lot of work in the provider model.
If you were to go the route I would think carefully how you exposed the data through URLs, and usually some of the complexity you talk of can be managed with use of sub-directories representing different views of the data (similar to a REST approach).
If you wish to avoid the provider model, then implementing a DA class is fairly straight forward. Typically a SQLiteOpenHelper is creatd as an inner class to the DA class (the open helper also providers basic versioning support) and an instance of this class is used to create database connections in the DA functions. There are many examples in the Android Source code. Look at any of the provider implementations, with MediaProvider.java probably being the most relevant as it uses quite complex searches for a provider. For example from the source code that is not a content provider see DbSSLSessionCache.java
Upvotes: 3
Reputation: 11057
If your data is just being accessed by your app then I would suggest skipping the content provider altogether. The reason being, it will add unnecessary layers between your app and the DB which won't help performance.
I recommend writing a class whose only job is to update/query the database. Then from your other classes/activities you can instantiate this DB access class to get data or put data.
You can have multiple instances of your DB class running at once.
Edit: Sample code snippets (I took the class definition and a couple methods from my working code) It was my first app, so its not perfect, but it works:
public class VoyagerDB extends SQLiteOpenHelper {
@Override
public void onCreate(SQLiteDatabase db) {
boolean ret = false;
// build out the schema
ret = populateSchema(db);
}
/**
* Returns information from a given obdRequest record.
* @param requestID
* @return
*/
public Cursor getRequestInfo (String requestID) {
Cursor c = null;
String sql = "SELECT id _id, active,request,formula, description,frequency,minValue,maxValue,numDataBytes " +
"FROM obdRequest " +
"WHERE ID=" + requestID;
c = localDBRW.rawQuery(sql, null);
return c;
}
/**
* If the given settings key exists in the DB, return its record ID. Otherwise return blank.
* @param key
* @return
*/
public String settingsKeyExists (String key) {
String recordID = "";
Cursor c = null;
String sql = "SELECT id,key,value from settings WHERE key = ?";
String selectionArgs[] = {key};
c = localDBRW.rawQuery(sql, selectionArgs);
if (c == null) {
return "";
}
if (c.getCount()<1) {
c.close();
return "";
}
c.moveToFirst();
recordID = c.getString(c.getColumnIndex("id"));
c.close();
return recordID;
}
}
Upvotes: 1