1 ContentProvider内容提供者
四大组件之一,实现不同程序实现数据的共享。联系人应用就使用了ContentProvider,比如你在自己的应用可以读取和修改联系人的数据(获得相应权限)。
其实它也是一个中间人,真正的数据源是文件或者SQLite。通过Uri向外暴露访问地址
2 ContentResolver内容解析者
一个应用通过ContentResolver可以访问另一个应用通过ContentProvider提供的数据(当然也可以在自己的应用中)。
3 ContentObserver内容观察者
监听数据库的变化,执行相应的操作。更新UI
mContentResolver.registerContentObserver(WicketProvider.CONTENT_URI, true, mChatObserver);
使用步骤
1 自定义UserContentProvider
a 自定义数据库工具类
b 自定义UserContentProvider继承ContentProvider 覆写对应的方法
创建,增删改查方法
1 public class UserContentProvider extends ContentProvider {
// 声明当前ContentProvider组件的唯一标识(Authority),注:必须使用小写字母
private static final StringAUTHORITY ="com.user.contentprovider.users";
2 @Override 3 public boolean onCreate() { 4 return false; 5 } 6 7 @Nullable 8 @Override 9 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 10 return null; 11 } 12 13 @Nullable 14 @Override 15 public String getType(Uri uri) { 16 return null; 17 } 18 19 @Nullable 20 @Override 21 public Uri insert(Uri uri, ContentValues values) { 22 return null; 23 } 24 25 @Override 26 public int delete(Uri uri, String selection, String[] selectionArgs) { 27 return 0; 28 } 29 30 @Override 31 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 32 return 0; 33 } 34 }
c 清单文件中配置provider
android:authorities="com.user.contentprovider.users" android:exported="true"/>
2 另一个应用中使用ContentResolver访问数据
1 public class MainActivity extends Activity{ 2 private TextView tv_info; 3 private ContentResolver resolver; 4 private Uri uri = Uri.parse("content://com.user.contentprovider.users/users"); 5 @Override 6 protected void onCreate(Bundle savedInstanceState) { 7 // TODO Auto-generated method stub 8 super.onCreate(savedInstanceState); 9 setContentView(R.layout.layout_main); 10 tv_info = (TextView)findViewById(R.id.tv_info); 11 resolver = getContentResolver(); 12 } 13 public void click(View v){ 14 switch (v.getId()) { 15 case R.id.bt_query: 16 //建表时的语句:create table t_user(_id integer primary key,uname,upass,money) 17 query();//调用自定义的查询所有数据的方法 18 break; 19 case R.id.bt_insert: 20 insert();//调用自定义的插入数据的方法 21 break; 22 case R.id.bt_update: 23 //请自行实现 24 break; 25 default: 26 break; 27 } 28 } 29 private void insert() { 30 //调用自定义的插入数据的方法(硬编码) 31 ContentValues values = new ContentValues(); 32 values.put("uname", "zhang"); 33 values.put("upass", "321"); 34 values.put("money", "99"); 35 Uri nUri = resolver.insert(uri, values);//sqlite会自动指定主键id 36 long newId = ContentUris.parseId(nUri);//获取新插入的id 37 Toast.makeText(this, ""+newId, 0).show(); 38 } 39 private void query() { 40 //自定义的查询所有数据的方法 41 Cursor c = resolver.query(uri , new String[]{"_id","uname","upass","money"}, null, null,null); 42 String text = ""; 43 while(c.moveToNext()){ 44 text +=c.getString(0)+","+c.getString(1)+","+c.getString(2)+","+c.getString(3)+"\n"; 45 } 46 tv_info.setText(text); 47 } 48 }
【备注:】
ContentProvider是单例模式的,当多个应用程序通过使用ContentResolver 来操作使用ContentProvider 提供的数据时,ContentResolver 调用的数据操作会委托给同一个ContentProvider 来处理。这样就能保证数据的一致性。
Cursor 游标,查询时返回的结果集
具体应用参考实际开发项目。
使用ContentProvider和ContentResolver时,是否可用第三方ORM数据库工具,如GreenDao操作数据库?
不建议使用。这两者是通过Uri来操作数据,而GreenDao是通过bean来操作数据库。
SQLiteDatabase 和 ContentResolver操作数据库api有所不同,前者操作对象为表,后者为Uri。