学习ContentProvider---之三:最简单的ContentProvider

看完Google的文档,我终于自己写出了一个简单的ContentProvider,并且写了另一个工程去使用它,现总结如下:

 

一、创建一个ContentProvider必备:

1.      Set up a system for storing the data,就是想好你用什么方式存储数据,你可以用任何你喜欢的方式存储,文件存储或SQLite数据库

2.      Extend the ContentProvider class to provide access to the data.

3.      Declare the content provider in the manifest file for your application (AndroidManifest.xml).就是写上类似这样的东西:

 

二、写一个类继承自ContentProvider,并且使用一个继承自SQLiteOpenHelper的类去管理database以及table的创建。


三、将override所有的unimplemented方法,即:

      query() 

 

       insert() 
update() 
delete() 
getType() 
onCreate()

 

四、需要写一个供使用者使用的类,这个类中必须公布给使用者用的CONTENT_URI,以及各个表的column名,并且最好用注释写好每个column的类型,以方便Provider的用户使用。例如我就写了一个类:

 

public class LilyUser {

 

public static class User{

public static final Uri CONTENT_URI = Uri.parse("content://com.ianc.lilyprovider/" + "customer");

}

public static class UserColumns implements BaseColumns{

public static String NAME = "name";

public static String PASSWORD = "password";

}

}这里面我就将整个类看成是一个database,然后里面User算成是一张表(其实表名是customer,这里名字还是没有命名好,应该一致的),而UserColumn则是这张表的所有column。这样的结构比较清晰易读。

 

五、在创建table的时候_ID很重要,文档中很明确说明了这一点:

1.Be sure to include an integer column named "_id" (with the constant _ID) for the IDs of the records.

2.假如设置了INTEGER PRIMARY KEY AUTOINCREMENT这个属性,那么不论数据库的数据是否被删除过,系统的id将一直增长,而假如不加AUTOINCREMENT这个属性,那么删除掉一条数据后空出的id,将在下一次新增数据时使用,例如有数据1,2,3条,现在删去第2条,再插入一条,那么新增的这一条id是2,假如设置了AUTOINCREMENT,那么则是4。

 

六、最后我想到一个方式如何在使用ContentProvider 的query时候去实现多表查询了,我想只要自己定义好uri的格式,然后在Provider的query里面去解析传来的uri,只要满足特定条件,就代表是多表查询就ok,这个方法我会下次试试。

 

 

我写了两个工程一个是LilyProvider,这个就是我写的ContentProvider了,另一个是TestLilyProvider,就是使用我写的这个provider啦。

附上主要的代码:

LilyUser.java:供Provider的使用者使用的类

package com.ianc.lilyprovider; import android.net.Uri; import android.provider.BaseColumns; public class LilyUser { public static class User{ public static final Uri CONTENT_URI = Uri.parse("content://com.ianc.lilyprovider/" + "customer"); } public static class UserColumns implements BaseColumns{ public static String NAME = "name"; public static String PASSWORD = "password"; } }  

 

LilyProvider.java:一个简单粗暴的ContentProvider

package com.ianc.lilyprovider; 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.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.net.Uri; import android.util.Log; public class LilyProvider extends ContentProvider { final String TABLE_NAME = "customer"; private static final String DATABASE_NAME = "lily.db"; private String AUTHORITY = "com.ianc.lilyprovider"; private static final int DATABASE_VERSION = 1; DatabaseHelper mDbHelper; static UriMatcher sUriMatcher; static{ // sUriMatcher.addURI(AUTHORITY, path, code) } class DatabaseHelper extends SQLiteOpenHelper { public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { Log.i("lily","LilyProvider-->DatabaseHelper-->onCreate"); db.execSQL("Create table " + TABLE_NAME + "( " + LilyUser.UserColumns._ID+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + LilyUser.UserColumns._COUNT + " INTEGER,"+ LilyUser.UserColumns.NAME + " TEXT," + LilyUser.UserColumns.PASSWORD +" TEXT" + ");"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.i("lily","LilyProvider-->DatabaseHelper-->onUpgrade"); db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME+";"); onCreate(db); } } @Override public int delete(Uri arg0, String arg1, String[] arg2) { Log.i("lily","LilyProvider-->delete"); SQLiteDatabase db = mDbHelper.getWritableDatabase(); int rownum = db.delete(TABLE_NAME, arg1, arg2); return rownum; } @Override public String getType(Uri uri) { Log.i("lily","LilyProvider-->getType"); return null; } @Override public Uri insert(Uri uri, ContentValues values) { Log.i("lily","LilyProvider-->insert"); SQLiteDatabase db = mDbHelper.getWritableDatabase(); db.insert(TABLE_NAME, null, values); return null; } @Override public boolean onCreate() { Log.i("lily","LilyProvider-->onCreate"); mDbHelper = new DatabaseHelper(this.getContext()); return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Log.i("lily","LilyProvider-->query"); SQLiteDatabase db = mDbHelper.getReadableDatabase(); Cursor c = db.query(TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder); return c; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { Log.i("lily","LilyProvider-->update"); SQLiteDatabase db = mDbHelper.getWritableDatabase(); int rownum = db.update(TABLE_NAME, values, selection, selectionArgs); return rownum; } }  

TestLilyProvider.java:例举一个简单的使用方法

package com.ianc.testlilyprovider; import com.ianc.lilyprovider.LilyUser; import android.app.Activity; import android.content.ContentUris; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class TestLilyProvider extends Activity implements OnClickListener { Button mQueryBtn; Button mInsertBtn; Button mUpdateBtn; Button mDeleteBtn; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mQueryBtn = (Button)findViewById(R.id.query); mInsertBtn = (Button)findViewById(R.id.insert); mUpdateBtn = (Button)findViewById(R.id.update); mDeleteBtn = (Button)findViewById(R.id.delete); mQueryBtn.setOnClickListener(this); mInsertBtn.setOnClickListener(this); mUpdateBtn.setOnClickListener(this); mDeleteBtn.setOnClickListener(this); } @Override public void onClick(View v) { if (v == mQueryBtn){ query(); } else if (v == mInsertBtn){ insert(); } else if (v == mUpdateBtn){ update(); } else if (v == mDeleteBtn){ delete(); } } private void query() { String[] projection = {LilyUser.UserColumns._ID, LilyUser.UserColumns.NAME, LilyUser.UserColumns.PASSWORD}; String selection = null; String [] selectionArgs = {"lily"}; String sortOrder = null; Cursor cursor = getContentResolver().query(LilyUser.User.CONTENT_URI, projection, LilyUser.UserColumns.NAME +" = ?", selectionArgs, sortOrder); if (cursor.moveToFirst()){ Log.i("lily","*********************************************"); String id; String name; String password; do{ id = cursor.getString(cursor.getColumnIndex(LilyUser.UserColumns._ID)); Log.i("lily","id = "+id); name = cursor.getString(cursor.getColumnIndex(LilyUser.UserColumns.NAME)); Log.i("lily","name = "+name); password = cursor.getString(cursor.getColumnIndex(LilyUser.UserColumns.PASSWORD)); Log.i("lily","password = "+password); Log.i("lily","*********************************************"); }while(cursor.moveToNext()); } else{ Log.i("lily","no result"); } cursor.close(); } private void insert() { ContentValues values = new ContentValues(); values.put(LilyUser.UserColumns.NAME, "lily"); values.put(LilyUser.UserColumns.PASSWORD, "19870528"); getContentResolver().insert(LilyUser.User.CONTENT_URI, values); } private void update() { ContentValues values = new ContentValues(); values.put(LilyUser.UserColumns.NAME, "lily"); values.put(LilyUser.UserColumns.PASSWORD, "ljy19870528"); String[] selectionArgs = {"lily"}; int num = getContentResolver().update(LilyUser.User.CONTENT_URI, values, LilyUser.UserColumns.NAME +" = ?", selectionArgs); Log.i("lily",num + " rows be updated"); } private void delete() { String[] selectionArgs = {"lily"}; int num = getContentResolver().delete(LilyUser.User.CONTENT_URI, LilyUser.UserColumns.NAME +" = ?", selectionArgs); Log.i("lily",num+" rows be deleted"); } } 

 

下一集我将会写得复杂一些,加上一些Uri的分析,多表查询,甚至muliprocess(Thread-safe)之类的,预知后事如何倾听下回分解。。。。。。

你可能感兴趣的:(android)