ContentProvider-3最简单的

本文介绍了一个简单的ContentProvider实现过程,包括设置数据存储方式、继承ContentProvider类、声明Provider、覆盖未实现的方法等步骤,并提供了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看完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).就是写上类似这样的东西:
<provider android:name="LilyProvider" android:authorities="com.ianc.lilyprovider" />
 
二、写一个类继承自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的使用者使用的类


view plaincopy to clipboardprint?
1. package com.ianc.lilyprovider;  
2. import android.net.Uri;  
3. import android.provider.BaseColumns;  
4. public class LilyUser {  
5.       
6.     public static class User{  
7.         public static final Uri CONTENT_URI = Uri.parse("content://com.ianc.lilyprovider/" + "customer");  
8.     }  
9.     public static class UserColumns implements BaseColumns{   
10.         public static String NAME = "name";  
11.         public static String PASSWORD = "password";  
12.     }  
13. }  
 
LilyProvider.java:一个简单粗暴的ContentProvider


view plaincopy to clipboardprint?
1. package com.ianc.lilyprovider;  
2. import android.content.ContentProvider;  
3. import android.content.ContentValues;  
4. import android.content.Context;  
5. import android.content.UriMatcher;  
6. import android.database.Cursor;  
7. import android.database.sqlite.SQLiteDatabase;  
8. import android.database.sqlite.SQLiteOpenHelper;  
9. import android.database.sqlite.SQLiteDatabase.CursorFactory;  
10. import android.net.Uri;  
11. import android.util.Log;  
12. public class LilyProvider extends ContentProvider {  
13.     final String TABLE_NAME = "customer";  
14.     private static final String  DATABASE_NAME = "lily.db";  
15.     private String AUTHORITY = "com.ianc.lilyprovider";  
16.     private static final int DATABASE_VERSION = 1;  
17.     DatabaseHelper mDbHelper;  
18.     static UriMatcher sUriMatcher;  
19.     static{  
20. //      sUriMatcher.addURI(AUTHORITY, path, code)  
21.     }  
22.     class DatabaseHelper extends SQLiteOpenHelper {  
23.         public DatabaseHelper(Context context) {  
24.             super(context, DATABASE_NAME, null, DATABASE_VERSION);  
25.         }  
26.         @Override  
27.         public void onCreate(SQLiteDatabase db) {  
28.             Log.i("lily","LilyProvider-->DatabaseHelper-->onCreate");  
29.             db.execSQL("Create table " + TABLE_NAME + "( " +  
30.                     LilyUser.UserColumns._ID+ " INTEGER PRIMARY KEY AUTOINCREMENT, " +  
31.                     LilyUser.UserColumns._COUNT + " INTEGER,"+  
32.                     LilyUser.UserColumns.NAME + " TEXT," +  
33.                     LilyUser.UserColumns.PASSWORD +" TEXT" +  
34.                     ");");  
35.         }  
36.         @Override  
37.         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
38.             Log.i("lily","LilyProvider-->DatabaseHelper-->onUpgrade");  
39.             db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME+";");  
40.             onCreate(db);  
41.         }  
42.           
43.     }  
44.     @Override  
45.     public int delete(Uri arg0, String arg1, String[] arg2) {  
46.         Log.i("lily","LilyProvider-->delete");  
47.         SQLiteDatabase db = mDbHelper.getWritableDatabase();  
48.         int rownum = db.delete(TABLE_NAME, arg1, arg2);  
49.         return rownum;  
50.     }  
51.     @Override  
52.     public String getType(Uri uri) {  
53.         Log.i("lily","LilyProvider-->getType");  
54.         return null;  
55.     }  
56.     @Override  
57.     public Uri insert(Uri uri, ContentValues values) {  
58.         Log.i("lily","LilyProvider-->insert");  
59.         SQLiteDatabase db = mDbHelper.getWritableDatabase();  
60.         db.insert(TABLE_NAME, null, values);  
61.         return null;  
62.     }  
63.     @Override  
64.     public boolean onCreate() {  
65.         Log.i("lily","LilyProvider-->onCreate");  
66.         mDbHelper = new DatabaseHelper(this.getContext());  
67.         return false;  
68.     }  
69.     @Override  
70.     public Cursor query(Uri uri, String[] projection, String selection,  
71.             String[] selectionArgs, String sortOrder) {  
72.         Log.i("lily","LilyProvider-->query");  
73.         SQLiteDatabase db = mDbHelper.getReadableDatabase();  
74.         Cursor c = db.query(TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);  
75.         return c;  
76.     }  
77.     @Override  
78.     public int update(Uri uri, ContentValues values, String selection,  
79.             String[] selectionArgs) {  
80.         Log.i("lily","LilyProvider-->update");  
81.         SQLiteDatabase db = mDbHelper.getWritableDatabase();  
82.         int rownum = db.update(TABLE_NAME, values, selection, selectionArgs);  
83.         return rownum;  
84.     }  
85. }  
 
TestLilyProvider.java:例举一个简单的使用方法


view plaincopy to clipboardprint?
1. package com.ianc.testlilyprovider;  
2. import com.ianc.lilyprovider.LilyUser;  
3. import android.app.Activity;  
4. import android.content.ContentUris;  
5. import android.content.ContentValues;  
6. import android.database.Cursor;  
7. import android.net.Uri;  
8. import android.os.Bundle;  
9. import android.util.Log;  
10. import android.view.View;  
11. import android.view.View.OnClickListener;  
12. import android.widget.Button;  
13. public class TestLilyProvider extends Activity implements OnClickListener {  
14.     Button mQueryBtn;  
15.     Button mInsertBtn;  
16.     Button mUpdateBtn;  
17.     Button mDeleteBtn;  
18.     /** Called when the activity is first created. */  
19.     @Override  
20.     public void onCreate(Bundle savedInstanceState) {  
21.         super.onCreate(savedInstanceState);  
22.         setContentView(R.layout.main);  
23.         mQueryBtn = (Button)findViewById(R.id.query);  
24.         mInsertBtn = (Button)findViewById(R.id.insert);  
25.         mUpdateBtn = (Button)findViewById(R.id.update);  
26.         mDeleteBtn = (Button)findViewById(R.id.delete);  
27.           
28.         mQueryBtn.setOnClickListener(this);  
29.         mInsertBtn.setOnClickListener(this);  
30.         mUpdateBtn.setOnClickListener(this);  
31.         mDeleteBtn.setOnClickListener(this);  
32.     }  
33.     @Override  
34.     public void onClick(View v) {  
35.         if (v == mQueryBtn){  
36.             query();  
37.         }  
38.         else if (v == mInsertBtn){  
39.             insert();  
40.         }  
41.         else if (v == mUpdateBtn){  
42.             update();  
43.         }  
44.         else if (v == mDeleteBtn){  
45.             delete();  
46.         }  
47.           
48.     }  
49.     private void query() {  
50.         String[] projection = {LilyUser.UserColumns._ID, LilyUser.UserColumns.NAME, LilyUser.UserColumns.PASSWORD};  
51.         String selection = null;  
52.         String [] selectionArgs = {"lily"};  
53.         String sortOrder = null;  
54.           
55.         Cursor cursor = getContentResolver().query(LilyUser.User.CONTENT_URI, projection, LilyUser.UserColumns.NAME +" = ?", selectionArgs, sortOrder);  
56.         if (cursor.moveToFirst()){  
57.             Log.i("lily","*********************************************");  
58.             String id;  
59.             String name;  
60.             String password;  
61.             do{  
62.                 id = cursor.getString(cursor.getColumnIndex(LilyUser.UserColumns._ID));  
63.                 Log.i("lily","id = "+id);  
64.                   
65.                 name = cursor.getString(cursor.getColumnIndex(LilyUser.UserColumns.NAME));  
66.                 Log.i("lily","name = "+name);  
67.                   
68.                 password = cursor.getString(cursor.getColumnIndex(LilyUser.UserColumns.PASSWORD));  
69.                 Log.i("lily","password = "+password);  
70.                   
71.                 Log.i("lily","*********************************************");  
72.             }while(cursor.moveToNext());  
73.         }  
74.         else{  
75.             Log.i("lily","no result");  
76.         }  
77.         cursor.close();  
78.     }  
79.       
80.     private void insert() {  
81.         ContentValues values = new ContentValues();  
82.         values.put(LilyUser.UserColumns.NAME, "lily");  
83.         values.put(LilyUser.UserColumns.PASSWORD, "19870528");  
84.         getContentResolver().insert(LilyUser.User.CONTENT_URI, values);  
85.     }  
86.       
87.     private void update() {  
88.         ContentValues values = new ContentValues();  
89.         values.put(LilyUser.UserColumns.NAME, "lily");  
90.         values.put(LilyUser.UserColumns.PASSWORD, "ljy19870528");  
91.         String[] selectionArgs = {"lily"};  
92.         int num = getContentResolver().update(LilyUser.User.CONTENT_URI, values, LilyUser.UserColumns.NAME +" = ?", selectionArgs);  
93.         Log.i("lily",num + " rows be updated");  
94.     }  
95.       
96.     private void delete() {  
97.         String[] selectionArgs = {"lily"};  
98.         int num = getContentResolver().delete(LilyUser.User.CONTENT_URI, LilyUser.UserColumns.NAME +" = ?", selectionArgs);  
99.         Log.i("lily",num+" rows be deleted");  
100.           
101.     }  
102. }  
<think>好的,用户想了解Android开发中ContentProvider的用法和示例。首先,我需要回顾ContentProvider的基本概念,它是Android四大组件之一,主要用于不同应用间的数据共享。接着,要说明它的核心作用,比如封装数据访问、提供统一接口等。 然后,用户可能需要知道如何创建自定义的ContentProvider。这包括继承ContentProvider类,实现必要的方法如query、insert、update、delete等。还需要提到在AndroidManifest.xml中注册Provider,并设置android:exported属性来控制是否对外暴露。引用中的内容提到android:exported=false可以限制仅供内部使用,这点很重要,特别是涉及安全性的问题,必须包含进去。 接下来,应该给出一个简单的示例代码,展示如何定义ContentProvider的子类,并实现各个方法。同时,示例中的UriMatcher和SQLiteOpenHelper的使用也是关键点,需要解释清楚。代码部分要注意使用正确的格式,并确保语法正确。 另外,用户可能关心ContentProvider的使用场景,比如数据共享、与CursorLoader结合使用等。还要提到ContentResolver的用法,因为这是访问Provider的主要方式。需要强调线程安全,引用中提到5.4节关于线程安全的内容,应该指出在实现时需要注意同步机制,避免多线程问题。 最后,生成相关问题时要围绕用户可能进一步想知道的内容,比如如何限制访问权限、与数据库交互的细节、性能优化等。确保问题覆盖常见的使用场景和潜在的问题点,帮助用户深入理解。 现在需要检查回答是否符合系统指令,比如行内公式是否正确使用(虽然这里可能用不上,但要注意其他格式要求),独立公式是否单独成段,中文回答,以及引用标识是否正确添加。同时,确保示例代码正确,并且引用的内容自然插入到回答中,比如在讲解注册Provider时引用[^2],在讲解线程安全时引用[^1]等。 总结步骤:介绍ContentProvider的作用,创建步骤,示例代码,使用场景,安全配置,线程安全,最后生成相关问题。确保每个部分都清晰,并且引用正确。</think>### ContentProviderAndroid开发中的使用及示例 ContentProviderAndroid四大组件之一,主要用于**跨应用数据共享**,提供标准化的数据访问接口。以下是其核心知识点: #### 一、核心作用 1. **数据封装**:将数据源(如SQLite、文件、网络)封装为统一的访问接口。 2. **跨进程通信**:通过URI标识数据路径,支持其他应用通过ContentResolver访问数据。 3. **权限控制**:通过AndroidManifest.xml定义读写权限,例如: ```xml <provider android:name=".MyContentProvider" android:authorities="com.example.provider" android:exported="false" <!-- 禁止外部访问 --> android:readPermission="android.permission.READ_DATA" android:writePermission="android.permission.WRITE_DATA"/> ``` 通过`android:exported=false`可限制仅供内部使用[^1]。 #### 二、自定义ContentProvider步骤 1. **继承ContentProvider类**并实现六个核心方法: ```java public class MyProvider extends ContentProvider { @Override public boolean onCreate() { // 初始化数据库等操作 return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // 查询数据逻辑 } // 实现insert、update、delete、getType方法 } ``` 2. **定义数据URI**: ```java private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { uriMatcher.addURI("com.example.provider", "books", 1); // 匹配路径:/books } ``` #### 三、数据访问示例 通过ContentResolver操作数据: ```java // 查询数据 Cursor cursor = getContentResolver().query( Uri.parse("content://com.example.provider/books"), null, null, null, null ); // 插入数据 ContentValues values = new ContentValues(); values.put("title", "Android Guide"); getContentResolver().insert(uri, values); ``` #### 四、线程安全与性能 1. **线程安全**:ContentProvider方法默认运行在主线程,需自行实现同步机制(如使用`synchronized`块)。 2. **数据库优化**:建议配合SQLiteOpenHelper管理数据库连接,避免频繁打开关闭。 #### 五、典型应用场景 1. 应用内多个模块共享同一数据库 2. 向系统提供数据(如自定义联系人存储) 3. 与SyncAdapter配合实现后台数据同步
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值