ContentProvider基本使用
为了在应用程序之间交换数据,android提供了ContentProvider,ContentProvider是不同应用程序之间进行数据交换的标准API,当一个应用程序需要把自己的数据暴露给其他程序使用时,该应用程序就可以通过提供ContentPRovider来实现,其他应用程序就可以通过ContentResolver来操作ContentProvider暴露的数据。
实现ContentProvider的步骤:
1)编写一个类,继承ContentProvider,并且重写里面的CRUD方法。
2)在androidmanifest.xml文件中注册provider。
在androidmanifest.xml中注册provider需要以下3个属性:
android:name provider的实现类。
android:authorities provider的uri。
android:exported provider是否暴露给其他程序。
ContentResovler操作ContentProvider:
1)获取ContentResolver,getContentResovler()方法来自于ContextWrapper,所以activity和service中都可以使用。
2)调用CURD方法,通过参数url,调用指定的ContentProvider的方法。
下面是一个demo,向contentProvider中插入一条数据,并且返回到listview中。
main.xml:
<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\" xmlns:tools=\"http://schemas.android.com/tools\" android:layout_width=\"match_parent\" android:layout_height=\"match_parent\" tools:context=\".Main\" > <ListView android:id=\"@+id/listview\" android:layout_width=\"match_parent\" android:layout_height=\"wrap_content\" /> </RelativeLayout>
MySQLiteOpenHelper类
package com.app.dao; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class MySQLiteOpenHelper extends SQLiteOpenHelper { public MySQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); } @Override public void onCreate(SQLiteDatabase db) { String create_sql = \"create table tb_test(_id integer primary key autoincrement,name,gender,age)\"; db.execSQL(create_sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
MyContentProvider类
package com.app.dao; import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; public class MyContentProvider extends ContentProvider{ MySQLiteOpenHelper helper=null; @Override public int delete(Uri arg0, String arg1, String[] arg2) { return 0; } @Override public String getType(Uri arg0) { // TODO Auto-generated method stub return null; } @Override public Uri insert(Uri arg0, ContentValues values) { String insert_sql=\"insert into tb_test values(null,\'wx\',\'boy\',17)\"; helper.getReadableDatabase().execSQL(insert_sql); return null; } @Override public boolean onCreate() { helper=new MySQLiteOpenHelper(this.getContext(),\"test.db3\",null,1); return true; } @Override public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4) { String query_sql=\"select * from tb_test\"; Cursor cursor=helper.getReadableDatabase().rawQuery(query_sql, null); return cursor; } @Override public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) { // TODO Auto-generated method stub return 0; } }
listview的显示界面show.xml
<?xml version=\"1.0\" encoding=\"utf-8\"?> <LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\" android:layout_width=\"match_parent\" android:layout_height=\"match_parent\" android:orientation=\"horizontal\" > <TextView android:id=\"@+id/name\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" /> <TextView android:id=\"@+id/gender\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:layout_marginLeft=\"60dp\" /> <TextView android:id=\"@+id/age\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:layout_marginLeft=\"60dp\" /> </LinearLayout>
Main.java
package com.app.main; import android.annotation.SuppressLint; import android.app.Activity; import android.content.ContentResolver; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.support.v4.widget.CursorAdapter; import android.widget.ListView; import android.widget.SimpleCursorAdapter; public class Main extends Activity { ContentResolver resolver = null; ListView lv = null; @SuppressLint(\"NewApi\") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); lv = (ListView) this.findViewById(R.id.listview); resolver = this.getContentResolver(); String str = \"content://com.app.test.db/\"; Uri uri = Uri.parse(str); resolver.insert(uri, null); Cursor cursor = resolver.query(uri, null, null, null, null); SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.show, cursor, new String[] { \"name\", \"gender\", \"age\" }, new int[] { R.id.name, R.id.gender, R.id.age }, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); lv.setAdapter(adapter); } }
实现效果:(执行了3次插入后的效果)
ContentProvider的单元测试
ContentProvider是android的四大组件之一,在编写代码的时候最好是加上单元测试,这样可以确定对数据的CRUD的正确。本篇文章主要介绍ContentProvider中两个主要辅助类的使用还有单元测试的在ContentProvider中的使用。
需要用到的两个辅助类:UriMatcher类和ContentUris类。
UriMatcher类:能够对输入的uri参数就行匹配,以确定对什么表执行什么样的操作。
ContentUris类:有些方法需要返回uri,运用此类可以方便的生成uri类。
对于单元测试,个人觉得非常有必要在今后写代码的时候使用,这样可以非常准确的确定代码的正确性。
使用单元测试的步骤:
1)加入instrumentation,这个部分的代码是固定,也可以完全在ADT提供的向导中导入。
<instrumentation android:name=\"android.test.InstrumentationTestRunner\" android:targetPackage=\"com.example.android_contentprovider\" > </instrumentation>
2)添加<uses-library>,这个部分的代码也是固定的写法。
<uses-library android:name=\"android.test.runner\" />
好了,必备的知识已经讲完了,现在上代码:
1)生成一个SQLiteDatabase类,这个是必需的类MySQLiteOpenHelper类
package com.app.db; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class MySQLiteOpenHelper extends SQLiteOpenHelper { private static String DB_NAME = \"test.db3\"; private static int VERSION = 1; public MySQLiteOpenHelper(Context context) { super(context, DB_NAME, null, VERSION); } @Override public void onCreate(SQLiteDatabase db) { //建表语句 String create_student = \"create table student(_id integer primary key autoincrement,name varchar(10),age integer,gender vachar(10))\"; db.execSQL(create_student); //千万不能执行这句 // db.close(); } @Override public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) { } }
然后添加我们需要的MyContentProvider类:
package com.app.contentprovider; import com.app.db.MySQLiteOpenHelper; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.util.Log; public class MyContentProvider extends ContentProvider { MySQLiteOpenHelper helper = null; private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); // 匹配单条记录 private static final int student = 1; // 匹配多条记录 private static final int students = 2; static { matcher.addURI(\"com.app.wx\", \"student/#\", student); matcher.addURI(\"com.app.wx\", \"student\", students); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase db = helper.getWritableDatabase(); int action = matcher.match(uri); switch (action) { // 匹配单条记录 case student: long id = ContentUris.parseId(uri); //获取单条记录的id号 String delete_id = \"_id=\" + id; if (selection != null) { delete_id += delete_id + \" and \" + selection; } db.delete(\"student\", delete_id, selectionArgs); break; // 匹配多条记录 case students: db.delete(\"student\", selection, selectionArgs); break; } return 0; } //必需实现这个方法,这个方法与intent有关系,以后再讲 @Override public String getType(Uri uri) { int code = matcher.match(uri); switch (code) { case student: return \"vnd.android.cursor.item/student_item\"; case students: return \"vnd.android.cursor.dir/students\"; default: return null; } } @Override public Uri insert(Uri uri, ContentValues values) { SQLiteDatabase db = helper.getWritableDatabase(); int action = matcher.match(uri); switch (action) { case students: long id1 = db.insert(\"student\", \"_id\", values); Log.i(\"--------\", ContentUris.withAppendedId(uri, id1).toString()); return ContentUris.withAppendedId(uri, id1); } return null; } @Override public boolean onCreate() { helper = new MySQLiteOpenHelper(this.getContext()); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String orderBy) { SQLiteDatabase db = helper.getWritableDatabase(); Cursor cursor = null; int action = matcher.match(uri); switch (action) { case students: cursor = db.query(\"student\", projection, selection, selectionArgs, null, null, orderBy); break; } System.out.println(\"-----------count:\" + cursor.getCount()); return cursor; } @Override public int update(Uri uri, ContentValues values, String selection, String[] arg3) { int count = -1; SQLiteDatabase db = helper.getWritableDatabase(); int action = matcher.match(uri); switch (action) { case student: // 以id来处理更新 long id = ContentUris.parseId(uri); String id_selection = \"_id=\" + id; if (selection != null && !selection.equals(\"\")) { id_selection = id_selection + \" and \" + values; } count = db.update(\"student\", values, id_selection, arg3); System.out.println(\"----------count:\" + count); break; } return count; } }
这个类很长,但是执行的方法都是比较常见的CURD的方法,重要的是UriMatcher和ContentUris类的使用。
接着执行单元测试类:Test
package com.app.contentprovider; import android.content.ContentResolver; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.test.AndroidTestCase; import android.util.Log; public class Test extends AndroidTestCase { public void insert() { ContentResolver resolver = this.getContext().getContentResolver(); String str = \"content://com.app.wx/student\"; ContentValues values = new ContentValues(); values.put(\"name\", \"wzq\"); values.put(\"age\", 18); values.put(\"gender\", \"boy\"); resolver.insert(Uri.parse(str), values); } public void update() { ContentResolver resolver = this.getContext().getContentResolver(); String str = \"content://com.app.wx/student/2\"; ContentValues values = new ContentValues(); values.put(\"name\", \"哈哈\"); resolver.update(Uri.parse(str), values, null, null); } public void query() { ContentResolver resolver = this.getContext().getContentResolver(); String str = \"content://com.app.wx/student\"; Uri uri = Uri.parse(str); Cursor cursor = resolver.query(uri, new String[] { \"_id\", \"name,age,gender\" }, null, null, \"_id desc\"); Log.d(\"------count\",cursor.getCount()+\"\"); } public void delete() { ContentResolver resolver = this.getContext().getContentResolver(); String str = \"content://com.app.wx/student/2\"; Uri uri = Uri.parse(str); long id=resolver.delete(uri, null, null); } }
执行insert方法之后(执行了三次):
执行了update方法之后:
执行了query方法之后:
执行了delete方法之后:
本文地址:https://www.stayed.cn/item/24477
转载请注明出处。
本站部分内容来源于网络,如侵犯到您的权益,请 联系我