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,他们的返回类型分别是

方法名 返回值类型 作用 onCreate boolean 初始化类容提供器的时候调用,返回ture表示初始化成功,否则初始化失败 getType String 根据传入的Uri返回对应的MIME insert Uri 添加数据,返回新数据的Uri update int 升级数据,返回升级的行数 query Cursor 查询数据库,返回储存有查询结果的Cursor delete int 删除数据,返回删除的行数

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,继续学习

0 0
原创粉丝点击