ContentProvider其实就是对数据加上一层封装,提供统一的接口来供应用程序来进行访问,例子对之前的数据库利用ContentProvider进行封装(应用程序的数据库只对本应用程序可用和可见,外部应用程序要想调用必须通过ContentProvider进行封装),封装完毕后利用ContentResolver对象来进行查询,示例代码如下:
public class UIDemo extends ContentProvider {
int version = 1;
public final String DB_NAME= "derekTest.db";
public final String TABLE_NAME= "table2";
private final String TABLE_ID="_id";
public final String TITLE= "title";
public final String BODY= "body";
DBHelper dbh = null;
class DBHelper extends SQLiteOpenHelper
{
public DBHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
String sql = "CREATE TABLE " + TABLE_NAME + " (" + TABLE_ID + " INTEGER PRIMARY KEY, " + TITLE
+ " text not null, " + BODY + " text not null " + ");";
String sql1 = "insert into "+ TABLE_NAME+" ("+TABLE_ID+", "+TITLE+", "+BODY+") values('1','hellokitty','stronger');";
String sql2 = "insert into "+ TABLE_NAME+" ("+TABLE_ID+", "+TITLE+", "+BODY+") values('2','micky','weaker');";
db.execSQL(sql);
db.execSQL(sql1);
db.execSQL(sql2);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean onCreate() {
dbh = new DBHelper(this.getContext(),DB_NAME,null,version);
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
SQLiteDatabase sqld=dbh.getReadableDatabase();
Cursor cursor =sqld.query(TABLE_NAME, new String[]{TABLE_ID,TITLE,BODY}, null, null, null, null, null);
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
}
UIDemo类继承ContentProvider类后需要实现其抽象方法即公布给外部的接口方法,在这里实现了query的方法
在activity中进行显示的时候:
public final String DB_AUTHORITY ="com.derek.xie.derekTest";
public final Uri DB_URI = Uri.parse("content://" + DB_AUTHORITY + "/table2");
上为自定义好的URI,authority需与manifest文件中对应
<provider android:name="com.derek.xie.UIDemo"
android:authorities="com.derek.xie.derekTest">
</provider>
注意manifest文件中添加(在application标签里)
Cursor cursor = this.getContentResolver().query(DB_URI, new String[]{TITLE,BODY}, null, null, null);
ListView ls = (ListView)this.findViewById(R.id.listview1);
SimpleCursorAdapter sca = new SimpleCursorAdapter(this,android.R.layout.simple_list_item_2,cursor,new String[]{TITLE ,BODY},new int[]{android.R.id.text1,android.R.id.text2 });
ls.setAdapter(sca);
首先利用getContentResolver()得到ContentResolver对象,调用Query方法传入定义好的URI,和需要的列的数据和查询条件返回Cursor对象
Tips:contentResolver和ContentProvider之间的关系非常简单,通过查看android源码,
ContentResolver类中的query方法可看到:
public final Cursor query(Uri uri, String[] projection,
String selection, String[] selectionArgs, String sortOrder) {
IContentProvider provider = acquireProvider(uri);
if (provider == null) {
return null;
}
……
Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder);
… …
}
Query方法实际上会先通过uri获得provider对象然后,调用我们自己实现的ContentProvider抽象类里面的query方法