android 实现一个ContentProvider对多张表进行操作

因为只有一个ContentProvider,所以在ContentProvider中就要区别多张表,很明确一下子就找到解决问题的切入点。下面的方法就是这样做的。也就是说authority只有一个,但Content_uri还是要有多个,因为要对应多张表。下面看代码:

直接操作数据类DatabaseHelper跟前面是一样的

DatabaseHelper.java

[java]  view plain  copy
  1. package com.jacp.database;  
  2.   
  3. import android.content.Context;  
  4. import android.database.sqlite.SQLiteDatabase;  
  5. import android.database.sqlite.SQLiteOpenHelper;  
  6.   
  7. import com.jacp.demo.provider.Provider;  
  8.   
  9. /** 
  10.  * 直接操作数据库类 
  11.  * @author jacp 
  12.  * 
  13.  */  
  14. public class DatabaseHelper extends SQLiteOpenHelper {  
  15.     private static final String DATABASE_NAME = "jacp_demo.db";  
  16.     private static final int DATABASE_VERSION = 1;  
  17.   
  18.     public DatabaseHelper(Context context) {  
  19.         super(context, DATABASE_NAME, null, DATABASE_VERSION);  
  20.     }  
  21.   
  22.     @Override  
  23.     public void onCreate(SQLiteDatabase db) {  
  24.         db.execSQL("CREATE TABLE " + Provider.ProgrammerColumns.TABLE_NAME + " ("  
  25.                 + Provider.ProgrammerColumns._ID + " INTEGER PRIMARY KEY,"  
  26.                 + Provider.ProgrammerColumns.NAME + " TEXT,"  
  27.                 + Provider.ProgrammerColumns.AGE + " INTEGER"  
  28.                 + ");");  
  29.           
  30.         db.execSQL("CREATE TABLE " + Provider.LeaderColumns.TABLE_NAME + " ("  
  31.                 + Provider.LeaderColumns._ID + " INTEGER PRIMARY KEY,"  
  32.                 + Provider.LeaderColumns.NAME + " TEXT,"  
  33.                 + Provider.LeaderColumns.TITLE + " TEXT,"  
  34.                 + Provider.LeaderColumns.LEVEL + " INTEGER"  
  35.                 + ");");  
  36.     }  
  37.   
  38.     @Override  
  39.     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
  40.         db.execSQL("DROP TABLE IF EXISTS " + Provider.ProgrammerColumns.TABLE_NAME);  
  41.         db.execSQL("DROP TABLE IF EXISTS " + Provider.LeaderColumns.TABLE_NAME);  
  42.         onCreate(db);  
  43.     }  
  44. }  
保存跟数据库及表有关的常量,里面只有一个authority:
Provider.java

[java]  view plain  copy
  1. package com.jacp.demo.provider;  
  2.   
  3. import android.net.Uri;  
  4. import android.provider.BaseColumns;  
  5.   
  6. /** 
  7.  * 保存数据库中的常量 
  8.  * @author jacp 
  9.  * 
  10.  */  
  11. public class Provider {  
  12.       
  13.     // 这里只有一个authority  
  14.     public static final String AUTHORITY = "com.jacp.provider.demo.common";  
  15.     public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.jacp.demo";  
  16.   
  17.     public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.jacp.demo";  
  18.   
  19.     /** 
  20.      * 保存programmer表中用到的常量 
  21.      * @author jacp 
  22.      * 
  23.      */  
  24.     public static final class ProgrammerColumns implements BaseColumns {  
  25.         // 注意这个地方和下面LeaderColumns类中CONTENT_URI一样,用的是同一个AUTHORITY  
  26.         public static final Uri CONTENT_URI = Uri.parse("content://"+ AUTHORITY +"/programmers");  
  27.         public static final String TABLE_NAME = "programmer";  
  28.         public static final String DEFAULT_SORT_ORDER = "age desc";  
  29.           
  30.         public static final String NAME = "name";  
  31.         public static final String AGE = "age";  
  32.           
  33.     }  
  34.       
  35.     /** 
  36.      * 保存leader表中用到的常量 
  37.      * @author mayliang 
  38.      * 
  39.      */  
  40.     public static final class LeaderColumns implements BaseColumns {  
  41.         public static final Uri CONTENT_URI = Uri.parse("content://"+ AUTHORITY +"/leaders");  
  42.         public static final String TABLE_NAME = "leader";  
  43.         public static final String DEFAULT_SORT_ORDER = "level desc";  
  44.           
  45.         public static final String NAME = "name";  
  46.         public static final String TITLE = "title";  
  47.         public static final String LEVEL = "level";  
  48.           
  49.     }  
  50.       
  51. }  
对多张表数据进行增删改查操作的ContentProvider类:

CommonProvider.java

[java]  view plain  copy
  1. package com.jacp.demo.provider;  
  2.   
  3. import java.util.HashMap;  
  4.   
  5. import android.content.ContentProvider;  
  6. import android.content.ContentUris;  
  7. import android.content.ContentValues;  
  8. import android.content.UriMatcher;  
  9. import android.database.Cursor;  
  10. import android.database.SQLException;  
  11. import android.database.sqlite.SQLiteDatabase;  
  12. import android.database.sqlite.SQLiteQueryBuilder;  
  13. import android.net.Uri;  
  14. import android.text.TextUtils;  
  15.   
  16. import com.jacp.database.DatabaseHelper;  
  17.   
  18. /** 
  19.  * 对programmer和leader表进行操作的ContentProvider 
  20.  * @author jacp 
  21.  * 
  22.  */  
  23. public class CommonProvider extends ContentProvider {  
  24.   
  25.     private static HashMap<String, String> sprogrammersProjectionMap;  
  26.   
  27.     private static final int PROGRAMMERS = 1;  
  28.     private static final int PROGRAMMERS_ID = 2;  
  29.       
  30.     // 这里要增加匹配项  
  31.     private static final int LEADERS = 3;  
  32.     private static final int LEADERS_ID = 4;  
  33.   
  34.     private static final UriMatcher sUriMatcher;  
  35.   
  36.     private DatabaseHelper mOpenHelper;  
  37.   
  38.     @Override  
  39.     public boolean onCreate() {  
  40.         mOpenHelper = new DatabaseHelper(getContext());  
  41.         return true;  
  42.     }  
  43.   
  44.     @Override  
  45.     public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,  
  46.             String sortOrder) {  
  47.         SQLiteQueryBuilder qb = new SQLiteQueryBuilder();  
  48.         String orderBy;  
  49.         switch (sUriMatcher.match(uri)) { // 这里要对不同表的匹配结果做不同处理  
  50.         case LEADERS:  
  51.         case LEADERS_ID:  
  52.             qb.setTables(Provider.LeaderColumns.TABLE_NAME);  
  53.             // If no sort order is specified use the default  
  54.             if (TextUtils.isEmpty(sortOrder)) {  
  55.                 orderBy = Provider.LeaderColumns.DEFAULT_SORT_ORDER;  
  56.             } else {  
  57.                 orderBy = sortOrder;  
  58.             }  
  59.             break;  
  60.         case PROGRAMMERS:  
  61.         case PROGRAMMERS_ID:  
  62.             qb.setTables(Provider.ProgrammerColumns.TABLE_NAME);  
  63.             // If no sort order is specified use the default  
  64.             if (TextUtils.isEmpty(sortOrder)) {  
  65.                 orderBy = Provider.ProgrammerColumns.DEFAULT_SORT_ORDER;  
  66.             } else {  
  67.                 orderBy = sortOrder;  
  68.             }  
  69.             break;  
  70.         default:  
  71.             throw new IllegalArgumentException("Unknown URI " + uri);  
  72.         }  
  73.   
  74.         switch (sUriMatcher.match(uri)) {  
  75.         case LEADERS:  
  76.         case PROGRAMMERS:  
  77.             qb.setProjectionMap(sprogrammersProjectionMap);  
  78.             break;  
  79.   
  80.         case PROGRAMMERS_ID:  
  81.             qb.setProjectionMap(sprogrammersProjectionMap);  
  82.             qb.appendWhere(Provider.ProgrammerColumns._ID + "=" + uri.getPathSegments().get(1));  
  83.             break;  
  84.               
  85.         case LEADERS_ID:  
  86.             qb.setProjectionMap(sprogrammersProjectionMap);  
  87.             qb.appendWhere(Provider.LeaderColumns._ID + "=" + uri.getPathSegments().get(1));  
  88.             break;  
  89.   
  90.         default:  
  91.             throw new IllegalArgumentException("Unknown URI " + uri);  
  92.         }  
  93.   
  94.         // Get the database and run the query  
  95.         SQLiteDatabase db = mOpenHelper.getReadableDatabase();  
  96.         Cursor c = qb.query(db, projection, selection, selectionArgs, nullnull, orderBy);  
  97.   
  98.         // Tell the cursor what uri to watch, so it knows when its source data changes  
  99.         c.setNotificationUri(getContext().getContentResolver(), uri);  
  100.         return c;  
  101.     }  
  102.   
  103.     @Override  
  104.     public String getType(Uri uri) {  
  105.         switch (sUriMatcher.match(uri)) { // 这里也要增加匹配项  
  106.         case LEADERS:  
  107.         case PROGRAMMERS:  
  108.             return Provider.CONTENT_TYPE;  
  109.         case PROGRAMMERS_ID:  
  110.         case LEADERS_ID:  
  111.             return Provider.CONTENT_ITEM_TYPE;  
  112.         default:  
  113.             throw new IllegalArgumentException("Unknown URI " + uri);  
  114.         }  
  115.     }  
  116.   
  117.     @Override  
  118.     public Uri insert(Uri uri, ContentValues initialValues) {  
  119.         ContentValues values;  
  120.         if (initialValues != null) {  
  121.             values = new ContentValues(initialValues);  
  122.         } else {  
  123.             values = new ContentValues();  
  124.         }  
  125.           
  126.         String tableName = "";  
  127.         String nullColumn = "";  
  128.         switch (sUriMatcher.match(uri)) { // 这里要对不同表的匹配结果做不同处理  
  129.         case LEADERS:  
  130.             tableName = Provider.LeaderColumns.TABLE_NAME;  
  131.             nullColumn = Provider.LeaderColumns.NAME;  
  132.             // Make sure that the fields are all set  
  133.             if (values.containsKey(Provider.LeaderColumns.NAME) == false) {  
  134.                 values.put(Provider.LeaderColumns.NAME, "");  
  135.             }  
  136.   
  137.             if (values.containsKey(Provider.LeaderColumns.TITLE) == false) {  
  138.                 values.put(Provider.LeaderColumns.TITLE, "");  
  139.             }  
  140.               
  141.             if (values.containsKey(Provider.LeaderColumns.LEVEL) == false) {  
  142.                 values.put(Provider.LeaderColumns.LEVEL, 0);  
  143.             }  
  144.             break;  
  145.         case PROGRAMMERS:  
  146.             tableName = Provider.ProgrammerColumns.TABLE_NAME;  
  147.             nullColumn = Provider.ProgrammerColumns.NAME;  
  148.             // Make sure that the fields are all set  
  149.             if (values.containsKey(Provider.ProgrammerColumns.NAME) == false) {  
  150.                 values.put(Provider.ProgrammerColumns.NAME, "");  
  151.             }  
  152.   
  153.             if (values.containsKey(Provider.ProgrammerColumns.AGE) == false) {  
  154.                 values.put(Provider.ProgrammerColumns.AGE, 0);  
  155.             }  
  156.             break;  
  157.         default:  
  158.             // Validate the requested uri  
  159.             throw new IllegalArgumentException("Unknown URI " + uri);  
  160.                   
  161.         }  
  162.   
  163.         SQLiteDatabase db = mOpenHelper.getWritableDatabase();  
  164.         long rowId = db.insert(tableName, nullColumn, values);  
  165.         if (rowId > 0) {  
  166.             Uri noteUri = ContentUris.withAppendedId(uri, rowId);  
  167.             getContext().getContentResolver().notifyChange(noteUri, null);  
  168.             return noteUri;  
  169.         }  
  170.   
  171.         throw new SQLException("Failed to insert row into " + uri);  
  172.     }  
  173.   
  174.     @Override  
  175.     public int delete(Uri uri, String where, String[] whereArgs) {  
  176.         SQLiteDatabase db = mOpenHelper.getWritableDatabase();  
  177.         int count;  
  178.         switch (sUriMatcher.match(uri)) { // 这里要对不同表的匹配结果做不同处理,注意下面用到的表名不要弄错了  
  179.         case PROGRAMMERS:  
  180.             count = db.delete(Provider.ProgrammerColumns.TABLE_NAME, where, whereArgs);  
  181.             break;  
  182.   
  183.         case PROGRAMMERS_ID:  
  184.             String programmerId = uri.getPathSegments().get(1);  
  185.             count = db.delete(Provider.ProgrammerColumns.TABLE_NAME, Provider.ProgrammerColumns._ID + "=" + programmerId  
  186.                     + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);  
  187.             break;  
  188.               
  189.         case LEADERS:  
  190.             count = db.delete(Provider.LeaderColumns.TABLE_NAME, where, whereArgs);  
  191.             break;  
  192.               
  193.         case LEADERS_ID:  
  194.             String leaderId = uri.getPathSegments().get(1);  
  195.             count = db.delete(Provider.LeaderColumns.TABLE_NAME, Provider.LeaderColumns._ID + "=" + leaderId  
  196.                     + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);  
  197.             break;  
  198.   
  199.         default:  
  200.             throw new IllegalArgumentException("Unknown URI " + uri);  
  201.         }  
  202.   
  203.         getContext().getContentResolver().notifyChange(uri, null);  
  204.         return count;  
  205.     }  
  206.   
  207.     @Override  
  208.     public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {  
  209.         SQLiteDatabase db = mOpenHelper.getWritableDatabase();  
  210.         int count;  
  211.         switch (sUriMatcher.match(uri)) { // 这里要对不同表的匹配结果做不同处理,注意下面用到的表名不要弄错了  
  212.         case PROGRAMMERS:  
  213.             count = db.update(Provider.ProgrammerColumns.TABLE_NAME, values, where, whereArgs);  
  214.             break;  
  215.   
  216.         case PROGRAMMERS_ID:  
  217.             String noteId = uri.getPathSegments().get(1);  
  218.             count = db.update(Provider.ProgrammerColumns.TABLE_NAME, values, Provider.ProgrammerColumns._ID + "=" + noteId  
  219.                     + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);  
  220.             break;  
  221.         case LEADERS:  
  222.             count = db.update(Provider.LeaderColumns.TABLE_NAME, values, where, whereArgs);  
  223.             break;  
  224.               
  225.         case LEADERS_ID:  
  226.             String leaderId = uri.getPathSegments().get(1);  
  227.             count = db.update(Provider.LeaderColumns.TABLE_NAME, values, Provider.LeaderColumns._ID + "=" + leaderId  
  228.                     + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);  
  229.             break;  
  230.   
  231.         default:  
  232.             throw new IllegalArgumentException("Unknown URI " + uri);  
  233.         }  
  234.   
  235.         getContext().getContentResolver().notifyChange(uri, null);  
  236.         return count;  
  237.     }  
  238.   
  239.     static {  
  240.         sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);  
  241.         sUriMatcher.addURI(Provider.AUTHORITY, "programmers", PROGRAMMERS);  
  242.         sUriMatcher.addURI(Provider.AUTHORITY, "programmers/#", PROGRAMMERS_ID);  
  243.           
  244.         // 这里要增加另一张表的匹配项  
  245.         sUriMatcher.addURI(Provider.AUTHORITY, "leaders", LEADERS);  
  246.         sUriMatcher.addURI(Provider.AUTHORITY, "leaders/#", LEADERS_ID);  
  247.   
  248.         // 保存所有表用到的字段  
  249.         sprogrammersProjectionMap = new HashMap<String, String>();  
  250.         sprogrammersProjectionMap.put(Provider.ProgrammerColumns._ID, Provider.ProgrammerColumns._ID);  
  251.         sprogrammersProjectionMap.put(Provider.ProgrammerColumns.NAME, Provider.ProgrammerColumns.NAME);  
  252.         sprogrammersProjectionMap.put(Provider.ProgrammerColumns.AGE, Provider.ProgrammerColumns.AGE);  
  253.           
  254.         sprogrammersProjectionMap.put(Provider.ProgrammerColumns._ID, Provider.ProgrammerColumns._ID);  
  255.         sprogrammersProjectionMap.put(Provider.ProgrammerColumns.NAME, Provider.ProgrammerColumns.NAME);  
  256.         sprogrammersProjectionMap.put(Provider.LeaderColumns.TITLE, Provider.LeaderColumns.TITLE);  
  257.         sprogrammersProjectionMap.put(Provider.LeaderColumns.LEVEL, Provider.LeaderColumns.LEVEL);  
  258.     }  
  259. }  
leader表对应的数据对象:

Leader.java

[java]  view plain  copy
  1. package com.jacp.pojos;  
  2.   
  3. public class Leader {  
  4.   
  5.     public String name;  
  6.     public String title;  
  7.     public int level;  
  8. }  
programmer表对应的数据对象:

Programmer.java

[java]  view plain  copy
  1. package com.jacp.pojos;  
  2.   
  3. public class Programmer {  
  4.   
  5.     public String name;  
  6.     public int age;  
  7. }  

用Activity测试:

[java]  view plain  copy
  1. package com.jacp.demo;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.ContentValues;  
  5. import android.database.Cursor;  
  6. import android.net.Uri;  
  7. import android.os.Bundle;  
  8. import android.text.TextUtils;  
  9. import android.util.Log;  
  10.   
  11. import com.jacp.demo.provider.Provider;  
  12. import com.jacp.pojos.Leader;  
  13. import com.jacp.pojos.Programmer;  
  14.   
  15. public class ContentProviderDemoActivity extends Activity {  
  16.       
  17.     private static final String TAG = "ProviderActivity";  
  18.       
  19.     @Override  
  20.     public void onCreate(Bundle savedInstanceState) {  
  21.         super.onCreate(savedInstanceState);  
  22.         setContentView(R.layout.main);  
  23.           
  24.         testLeader();  
  25.         testProgrammer();  
  26.     }  
  27.       
  28.     private void testProgrammer() {  
  29.         Programmer p = new Programmer();  
  30.         p.name = "jacp";  
  31.         p.age = 99;  
  32.         int id = insertProgrammer(p);  
  33.         queryProgrammer(id);  
  34.     }  
  35.       
  36.     private int insertProgrammer(Programmer programmer) {  
  37.         ContentValues values = new ContentValues();  
  38.         values.put(Provider.ProgrammerColumns.NAME, programmer.name);  
  39.         values.put(Provider.ProgrammerColumns.AGE, programmer.age);  
  40.         Uri uri = getContentResolver().insert(Provider.ProgrammerColumns.CONTENT_URI, values);  
  41.         Log.i(TAG, "insert uri="+uri);  
  42.         String lastPath = uri.getPathSegments().get(1);  
  43.         if (TextUtils.isEmpty(lastPath)) {  
  44.             Log.i(TAG, "insert failure!");  
  45.         } else {  
  46.             Log.i(TAG, "insert success! the id is " + lastPath);  
  47.         }  
  48.           
  49.         return Integer.parseInt(lastPath);  
  50.     }  
  51.       
  52.     private void queryProgrammer(int id) {  
  53.         Cursor c = getContentResolver().query(Provider.ProgrammerColumns.CONTENT_URI, new String[] { Provider.ProgrammerColumns.NAME, Provider.ProgrammerColumns.AGE }, Provider.ProgrammerColumns._ID + "=?"new String[] { id + "" }, null);  
  54.         if (c != null && c.moveToFirst()) {  
  55.             Programmer p = new Programmer();  
  56.             p.name = c.getString(c.getColumnIndexOrThrow(Provider.ProgrammerColumns.NAME));  
  57.             p.age = c.getInt(c.getColumnIndexOrThrow(Provider.ProgrammerColumns.AGE));  
  58.             c.close(); // 用完Cursor要释放资源,如果Cursor没有关闭系统会打出Error级别的Log  
  59.             Log.i(TAG, "programmer.name="+p.name+"---programmer.age="+p.age);  
  60.         } else {  
  61.             Log.i(TAG, "query failure!");  
  62.         }  
  63.     }  
  64.       
  65.     private void testLeader() {  
  66.         Leader leader = new Leader();  
  67.         leader.name = "jacky";  
  68.         leader.title = "CTO";  
  69.         leader.level = 30;  
  70.         int id = insertLeader(leader);  
  71.         queryLeader(id);  
  72.     }  
  73.       
  74.     private int insertLeader(Leader leader) {  
  75.         ContentValues values = new ContentValues();  
  76.         values.put(Provider.LeaderColumns.NAME, leader.name);  
  77.         values.put(Provider.LeaderColumns.TITLE, leader.title);  
  78.         values.put(Provider.LeaderColumns.LEVEL, leader.level);  
  79.         Uri uri = getContentResolver().insert(Provider.LeaderColumns.CONTENT_URI, values);  
  80.         Log.i(TAG, "insert uri="+uri);  
  81.         String lastPath = uri.getLastPathSegment();  
  82.         if (TextUtils.isEmpty(lastPath)) {  
  83.             Log.i(TAG, "insert failure!");  
  84.         } else {  
  85.             Log.i(TAG, "insert success! the id is " + lastPath);  
  86.         }  
  87.           
  88.         return Integer.parseInt(lastPath);  
  89.     }  
  90.       
  91.     private void queryLeader(int id) {  
  92.         Cursor c = getContentResolver().query(Provider.LeaderColumns.CONTENT_URI, new String[] { Provider.LeaderColumns.NAME, Provider.LeaderColumns.TITLE, Provider.LeaderColumns.LEVEL }, Provider.LeaderColumns._ID + "=?"new String[] { id + "" }, null);  
  93.         if (c != null && c.moveToFirst()) {  
  94.             Leader leader = new Leader();  
  95.             leader.name = c.getString(c.getColumnIndexOrThrow(Provider.LeaderColumns.NAME));  
  96.             leader.title = c.getString(c.getColumnIndexOrThrow(Provider.LeaderColumns.TITLE));  
  97.             leader.level = c.getInt(c.getColumnIndexOrThrow(Provider.LeaderColumns.LEVEL));  
  98.             Log.i(TAG, "leader.name="+leader.name+"---leader.title="+leader.title+"---leader.level="+leader.level);  
  99.         } else {  
  100.             Log.i(TAG, "query failure!");  
  101.         }  
  102.     }  
  103. }  

Manifest.xml文件中的配置:

[java]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.jacp.demo"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.   
  7.     <uses-sdk android:minSdkVersion="8" />  
  8.   
  9.     <application  
  10.         android:icon="@drawable/ic_launcher"  
  11.         android:label="@string/app_name" >  
  12.         <activity  
  13.             android:label="@string/app_name"  
  14.             android:name=".ContentProviderDemoActivity" >  
  15.             <intent-filter >  
  16.                 <action android:name="android.intent.action.MAIN" />  
  17.   
  18.                 <category android:name="android.intent.category.LAUNCHER" />  
  19.             </intent-filter>  
  20.         </activity>  
  21.           
  22.         <!-- 这里只注册了一个ContentProvider,要注意的地方和前面一样 -->  
  23.         <provider android:name=".provider.CommonProvider"  
  24.             android:authorities="com.jacp.provider.demo.common" />  
  25.           
  26.     </application>  
  27.   
  28. </manifest>  
到此为止ContentProvider用法总结基本结束,有人会问了,什么时候用多个?什么时候用一个?我给的答案是看个人习惯及自己的需求,如果觉得以后这张表会被删除,那么最好是分开写,写多个ContentProvider,这样容易区分。有人又会问用ContentProvider不就是多余的,项目里面的数据不会跟外部共享,所以不需要ContentProvider,直接操作数据库得了。也没错,用了ContentProvider基本上是公开了数据,但个人感觉用ContentProvider的好处是在项目架构上面降低了类与类之间的耦合性,直接用Content_uri就可以对表进行操作,其它不管系统是怎么调用的,感觉这一点还是比较好,所以推荐。

OK,就写到这里了,睡觉 ^ _ ^

demo下载地址:http://download.csdn.net/detail/maylian7700/4150144

如有遗漏不当之处,欢迎批评指正!

另外再推荐一个学习ContentProvider的博客:https://blog.csdn.net/anddlecn/article/category/6273447

猜你喜欢

转载自blog.csdn.net/xiao5678yun/article/details/81005942