从实例理解ContentProvider用法

ContentProvider实例详解与应用
本文介绍了ContentProvider的工作原理和代码实现,包括如何创建数据库、定义ContentProvider子类以及在AndroidManifest中注册。通过理解ContentProvider的query方法和SQLite数据库的使用,可以实现对数据的查询和操作。

原理部分1-2

代码实现部分3-5

原理部分开始--------------------------------------------------------------------------------------------------------------------------------------------

1.ContentProvider是一个抽象类,不能直接使用,需要把它实例化,重新定义一个非抽象类继承ContentProvider。

需要重写以下几个方法:

public class MyProvider extends ContentProvider {
    private SQLiteDatabase sqLiteDatabase;
    @Override
    public boolean onCreate() {
        return false;
    }

    @Override
    public String getType( Uri uri) {
        return null;
    }

    @Override
    public Uri insert( Uri uri, ContentValues values) {
        return null;
    }

    @Override
    public Cursor query( Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        String name ="name";
        if(uri == null){
            throw new IllegalArgumentException("Unsupported URI:" + uri);
        }
        return sqLiteDatabase.query(name, projection, selection, selectionArgs,null,null, sortOrder,null);
    }

    @Override
    public int update( Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        return 0;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }
}

并在AndroidManifest里注册

        <provider
            android:authorities="com.example.administrator.model.MyProvider"
            android:name=".MyProvider"/>

2.从1中可以看到,query方法中使用到了sqLiteDatabase,而sqLiteDatabase是一个抽象方法,所以需要创建一个类来实现sqLiteDatabase.只需要重写oncreate方法。

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

操作数据库,只要实现以上两个类就足够了。

原理部分结束-------------------------------------------------------------------------------------------------------------------------------------------

下面是代码实现部分---------------------------------------------------------------------------------------

3先实现database

package com.example.administrator.model;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseOpenHelper extends SQLiteOpenHelper {
    private static final String DATA_BASE_NAME = "movie.db";//创一个叫建movie.db的数据库
    public static final String TABLE_NAME = "casttable";//这是即将创建的表的名称
    private static final int DATA_BASE_VERSION = 1;//这个值最低为1,用来让计算机识别匹配数据库
    /*实现构造方法,每个类必须有的,参数就是上面定义好的,直接用。*/
    public DatabaseOpenHelper(Context context){
        super(context,DATA_BASE_NAME,null,DATA_BASE_VERSION);//调用父类构造方法就可以了
    }
    /*sql语句,用来创建表,此处创建了四个键,其中_id为主键,主键与表项一一对应,不可重复。*/
    private final String CREATE_CAST_TABLE = "create table " + TABLE_NAME + "(_id integer primary key autoincrement, name text,age integer,sex text)";
    @Override
    public void onCreate(SQLiteDatabase db) {
        //用已经写好的语句来创建表
        db.execSQL(CREATE_CAST_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

4实现myprovider

package com.example.administrator.model;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;

public class MyProvider extends ContentProvider {
    private SQLiteDatabase sqLiteDatabase;
    Context context;
    /*注意此处是public关键字,所以注意authority名称不可以和其他数据库的authority混淆*/
    public static final String AUTHORITY2 = "com.example.administrator.model.MyProvider";
    //创建一个新的urimatcher,随后作绑定用
    public static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    //用表名获得uri,以下static表示类被加载时仅执行一次
    static{uriMatcher.addURI(AUTHORITY2,DatabaseOpenHelper.TABLE_NAME,0);}
    /*通过uri获得表名的方法*/
    private String getTableName(Uri uri) {
        String tableName = null;
         tableName = DatabaseOpenHelper.TABLE_NAME;
        return tableName;
    }

    public MyProvider(){ };//构造方法必不可少

    private void initialData(){
        context = getContext();
        //因为要使用SQLiteDatabase的query功能,所以创建时不使用DatabaseOpenHelper,而使用其父类SQLiteDatabase。
        sqLiteDatabase = new DatabaseOpenHelper(context).getWritableDatabase();
        //用父类创建变量,用子类来实现变量,这叫做对象的多态,向上转型。
        sqLiteDatabase.beginTransaction();//数据库开始工作
        ContentValues contentValues = new ContentValues();//新建一个表项
        //给表项的key添加值,注意id是自从生成的,不用我们手动添加,否则报错。
        contentValues.put("Name","杨幂");
        contentValues.put("Sex","女");
        contentValues.put("Age",20);
        //将我们创建的表项插入表中
        sqLiteDatabase.insert(DatabaseOpenHelper.TABLE_NAME,null,contentValues);
        //清空表项,装入新值。
        contentValues.clear();
        contentValues.put("Name","杨颖");
        contentValues.put("Sex","女");
        contentValues.put("Age",18);
        sqLiteDatabase.insert(DatabaseOpenHelper.TABLE_NAME,null,contentValues);
        contentValues.clear();
        //数据库创建完成
        sqLiteDatabase.setTransactionSuccessful();
        sqLiteDatabase.endTransaction();
    }
    @Override
    public boolean onCreate() {
        initialData();//完成初始化数据方法
        return false;
    }

    /*以下增删查改方法很简单就不多说了*/
    @Override
    public String getType( Uri uri) {
        return null;
    }

    @Override
    public Uri insert( Uri uri, ContentValues values) {
        String tableName = getTableName(uri);
        if (tableName == null) {
            throw new IllegalArgumentException("Unsupported URI:" + uri);
        }
        sqLiteDatabase.insert(tableName, null, values);
        context.getContentResolver().notifyChange(uri, null);
        return uri;
    }

    @Override
    public Cursor query( Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        String tableName = getTableName(uri);
        if (tableName == null) {
            throw new IllegalArgumentException("Unsupported URI:" + uri);
        }
        return sqLiteDatabase.query(tableName, projection, selection, selectionArgs,null,null, sortOrder,null);
    }

    @Override
    public int update( Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        String tableName = getTableName(uri);
        if (tableName == null) {
            throw new IllegalArgumentException("Unsupported URI:" + uri);
        }
        int row = sqLiteDatabase.update(tableName, values, selection, selectionArgs);
        if (row > 0) {
            context.getContentResolver().notifyChange(uri, null);
        }
        return row;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        String tableName = getTableName(uri);
        if (tableName == null) {
            throw new IllegalArgumentException("Unsupported URI:" + uri);
        }
        int count = sqLiteDatabase.delete(tableName, selection, selectionArgs);
        if (count > 0) {
            context.getContentResolver().notifyChange(uri, null);
        }
        return count;
    }
}

privder需要注册一下

        <provider
            android:authorities="com.example.administrator.model.MyProvider"
            android:name=".MyProvider"
            android:exported="true"/>

5.下面就可以使用数据库了

package com.example.administrator.model;

import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;

public class MyProviderActivity extends Activity {
    @Override
    protected void onCreate( Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_provider_view);
        //获得数据表的uri
        Uri castUri = Uri.parse("content://com.example.administrator.model.MyProvider/casttable");
        //创建一个用来查询的游标,游标是自己移动继续查找的,非常智能。
        Cursor castCursor = getContentResolver().query(castUri, new String[]{"_id", "name", "age","sex"}, null, null, null);
        if(castCursor != null){
            //将查询到的结果用log打印出来
            while(castCursor.moveToNext()){
                Log.d("querycast", " _id:"+castCursor.getInt(castCursor.getColumnIndex("_id"))
                        +" name:"+castCursor.getString(castCursor.getColumnIndex("name"))
                        +" sex:"+castCursor.getString(castCursor.getColumnIndex("sex"))
                        +" age:"+castCursor.getInt(castCursor.getColumnIndex("age")));
            }
            castCursor.close();
        }
    }
}

查询结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值