Android学习-四大组件(ContentProvider)
来源:互联网 发布:考研政治选择题知乎 编辑:程序博客网 时间:2024/05/26 12:07
今天继续复习内容提供者,ContentProvider可以实现不同程序之间的数据共享和数据操作。今天就来通过使用ContentProvider,来实现用一个程序来操作另一个程序的数据库。
ContentProvider
第一个程序用来当做被操作者,里面新建两个自定义类,分别是MySQLite继承自SQLiteOpenHelper,用来创建数据库,另外一个类叫MyProvider继承自ContentProvider。
MySQLite
public class MySQLite extends SQLiteOpenHelper{ private static final String CREATE="create table people(" + "id integer primary key autoincrement," + "name text," + "age integer," + "money real)"; public MySQLite(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 db.execSQL(CREATE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub }}
今天写代码的时候写快了把id integer primary key autoincrement写漏了,导致后面各种ANR,一定要仔细。
MyProvider
ContentProvider里面一共有六个类要进行重写,分别是onCreate、getType、insert、update、query、delete,他们的返回类型分别是
MIME
1.必须以vnd开头。
2.如果内容URI以路径结尾,则后接android.cursor.dir/,如果内容URI以id结尾,则后接android.cursor.item/。
3.最后接上vnd..。
getType中对于不同种类的Uri有不同的返回种类
1.Uri不含id的,如:
content://com.example.provider.newprovider/people
此时,对应的MIME就是:
vnd.android.cursor.dir/vnd.com.example.provider.newprovider.people
2.Uri包含id,如:
content://com.example.provider.newprovider/people/1
此时,对应的MIME就是:
vnd.android.cursor.item/vnd.com.example.provider.newprovider.people
在重写这几个方法之前,先定义一些后面需要的东西
private static final int PEOPLE_TABLE=0;//uri指向people这个表的时候 private static final int PEOPLE_ITEM=1;//uri指向people表中的某个id对应的行的时候 private static final String PROVIDER="com.example.provider.newprovider";//权限名 private static UriMatcher uriMarcher;//用来匹配uri private MySQLite mydb;//新建数据库要用到 private static SQLiteDatabase database;//操作数据库要用到static{ uriMarcher=new UriMatcher(UriMatcher.NO_MATCH);//实例化UriMatcher uriMarcher.addURI(PROVIDER, "people", PEOPLE_TABLE);//添加uri识别到uriMatcher中去 uriMarcher.addURI(PROVIDER, "people/#", PEOPLE_ITEM); }
onCreate
直接在里面新建一个数据库,并返回true
@Override public boolean onCreate() { // TODO Auto-generated method stub mydb=new MySQLite(getContext(), "people.db", null, 1); return true; }
getType
根据前面所记录的来写
@Override public String getType(Uri uri) { // TODO Auto-generated method stub String type=null; switch (uriMarcher.match(uri)) { case PEOPLE_TABLE: type="vnd.android.cursor.dir/vnd."+PROVIDER+".people"; break; case PEOPLE_ITEM: type="vnd.android.cursor.item/vnd."+PROVIDER+".people"; break; default: break; } return type; }
insert
@Override public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub database=mydb.getWritableDatabase(); Uri newUri=null;//储存要返回的新uri long id=database.insert("people", null, values); newUri=Uri.parse(PROVIDER+"/people/"+id); return newUri; }
update
@Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub database=mydb.getWritableDatabase(); int updateRows=0; switch (uriMarcher.match(uri)) { case PEOPLE_TABLE://没指明id就根据传入的数据来操作 updateRows=database.update("people", values, selection, selectionArgs); break; case PEOPLE_ITEM://指明了id,那么就操作id=?那一行 updateRows=database.update("people", values, "id=?", new String[]{uri.getPathSegments().get(1)}); break; default: break; } return updateRows;//返回被操作的行数 }
其中uri.getPathSegments().get(1)它会将内容URI权限之后的部分以“/”符号进行分割,并把分割后的结果放入到一个字符串列表中,那这个列表的第0个位置存放的就是路径,第1个位置存放的就是id了
delete
@Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub database=mydb.getReadableDatabase(); int deleteRows=0; switch (uriMarcher.match(uri)) { case PEOPLE_TABLE: deleteRows=database.delete("people", selection, selectionArgs); break; case PEOPLE_ITEM: deleteRows=database.delete("people", "id=?", new String[]{uri.getPathSegments().get(1)}); break; default: break; } return deleteRows; }
query
@Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub Cursor cursor=null; database=mydb.getReadableDatabase(); String id=null; switch (uriMarcher.match(uri)) { case PEOPLE_TABLE: cursor=database.query("people", projection, selection, selectionArgs, null, null, sortOrder); break; case PEOPLE_ITEM: id=uri.getPathSegments().get(1); cursor=database.query("people", projection, "id=?", new String[]{id}, null, null, sortOrder); break; default: break; } return cursor; }
AndroidManifest
重写完了之后还需要到AndroidManifest里面申明
<provider android:name=".MyProvider" android:authorities="com.example.provider.newprovider" android:exported="true"/>//是否可以被其他程序操作
ContentResolver
新建ContentResolver cResolver=getContentResolver();直接调用的context里面的方法
然后事先写好四个按钮,insert,delete,update,query分别对数据库进行添加数据、删除数据、升级数据、显示people表内的内容
public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.btn_insert: cValues.put("name", "张三"); cValues.put("age", i); cValues.put("money", i+2.33); i++; uri=Uri.parse(PROVIDER); Uri newUri=cResolver.insert(uri, cValues); newID=newUri.getPathSegments().get(2);//??这里get(1)获得的并不是新的id,而是uri中的Path,不知道为什么 cValues.clear(); break; case R.id.btn_delete: uri=Uri.parse(PROVIDER+"/"+newID); cResolver.delete(uri, null, null); break; case R.id.btn_update: uri=Uri.parse(PROVIDER+"/"+newID); cValues.put("name", "李四"); cResolver.update(uri, cValues, null, null); cValues.clear(); break; case R.id.btn_query: uri=Uri.parse(PROVIDER); Cursor cursor=null; cursor=cResolver.query(uri, null, null, null, null); showTable(cursor, textView); break; default: break; } } private void showTable(Cursor cursor,TextView textView) { StringBuffer sBuffer=new StringBuffer(); if (cursor!=null) { while (cursor.moveToNext()) { int id=cursor.getInt(cursor.getColumnIndex("id")); String name=cursor.getString(cursor.getColumnIndex("name")); int age=cursor.getInt(cursor.getColumnIndex("age")); double money=cursor.getDouble(cursor.getColumnIndex("money")); sBuffer.append(id+"\t"+name+"\t"+age+"\t"+money+"\n"); } textView.setText(sBuffer.toString()); sBuffer.delete(0, sBuffer.length()-1); } }
OK,继续学习
- Android学习-四大组件(ContentProvider)
- Android 四大组件学习之ContentProvider一
- Android 四大组件学习之ContentProvider二
- Android 四大组件学习之ContentProvider三
- Android 四大组件学习之ContentProvider四
- Android 四大组件学习之ContentProvider五
- Android学习之路--四大组件--ContentProvider
- Android四大组件学习之ContentProvider
- Android四大组件-ContentProvider
- Android四大组件-ContentProvider
- android四大组件---ContentProvider
- android四大组件--ContentProvider
- android四大组件--ContentProvider
- Android四大组件ContentProvider
- 【Android】四大组件(4)ContentProvider
- Android四大组件之ContentProvider(上)
- Android四大组件之ContentProvider(下)
- Android 四大组件(三)ContentProvider
- hanoi
- 共轴双桨直升机飞行原理介绍
- Python执行系统命令的方法
- 程序员面试题精选100题(13)-第一个只出现一次的字符[算法]
- Web之旅小结——BS和CS的对比
- Android学习-四大组件(ContentProvider)
- 利用 diskpart 隐藏显示分区
- 程序员面试题精选100题(14)-圆圈中最后剩下的数字[算法]
- 微观经济学-- 第2章 像经济学家一样思考
- windows下启动mysql服务的命令行启动和手动启动方法
- My Friends and I 我和我的小伙伴们
- puttty中文版终极版本
- OpenJudge百炼习题解答(C++)--题4072:判断多个点是否在同一直线
- 程序员面试题精选100题(15)-含有指针成员的类的拷贝[C/C++/C#]