zoukankan      html  css  js  c++  java
  • contentprovider的学习实例总结

    工作中遇到了contentprovider数据共享机制,下面来总结一下:

    一、ContentProvider简介
           当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读写数据。而使用ContentProvider共享数据的好处是统一了数据访问方式。
    二、Uri类简介
           Uri代表了要操作的数据,Uri主要包含了两部分信息:1.需要操作的ContentProvider ,2.对ContentProvider中的什么数据进行操作,一个Uri由以下几部分组成:

           1.scheme:ContentProvider(内容提供者)的scheme已经由Android所规定为:content://。
           2.主机名(或Authority):用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。
           3.路径(path):可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
    •         要操作contact表中id为10的记录,可以构建这样的路径:/contact/10
    •         要操作contact表中id为10的记录的name字段, contact/10/name
    •         要操作contact表中的所有记录,可以构建这样的路径:/contact
    要操作的数据不一定来自数据库,也可以是文件等他存储方式,如下:
    要操作xml文件中contact节点下的name节点,可以构建这样的路径:/contact/name
    如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:
    Uri uri = Uri.parse("content://com.changcheng.provider.contactprovider/contact")
    三、UriMatcher、ContentUrist和ContentResolver简介
           因为Uri代表了要操作的数据,所以我们很经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris 。掌握它们的使用,会便于我们的开发工作。

           UriMatcher:用于匹配Uri,它的用法如下:
           1.首先把你需要匹配Uri路径全部给注册上,如下:
           //常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码(-1)。
           UriMatcher  uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
           //如果match()方法匹配content://com.changcheng.sqlite.provider.contactprovider/contact路径,返回匹配码为1
           uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”, “contact”, 1);//添加需要匹配uri,如果匹配就会返回匹配码
           //如果match()方法匹配   content://com.changcheng.sqlite.provider.contactprovider/contact/230路径,返回匹配码为2
           uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”, “contact/#”, 2);//#号为通配符
          
           2.注册完需要匹配的Uri后,就可以使用uriMatcher.match(uri)方法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用addURI()方法传入的第三个参数,假设匹配content://com.changcheng.sqlite.provider.contactprovider/contact路径,返回的匹配码为1。

           ContentUris:用于获取Uri路径后面的ID部分,它有两个比较实用的方法:
    •         withAppendedId(uri, id)用于为路径加上ID部分
    •         parseId(uri)方法用于从路径中获取ID部分

           ContentResolver:当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver使用insert、delete、update、query方法,来操作数据。
    四、ContentProvider示例程序
    Manifest.xml中的代码

    01 <application android:icon="@drawable/icon" android:label="@string/app_name">
    02                 <activity android:name=".TestWebviewDemo" android:label="@string/app_name">
    03                         <intent-filter>
    04                                 <action android:name="android.intent.action.MAIN" />
    05                                 <category android:name="android.intent.category.LAUNCHER" />
    06                         </intent-filter>
    07                         <intent-filter>
    08                                 <data android:mimeType="vnd.android.cursor.dir/vnd.ruixin.login" />
    09                         </intent-filter>
    10                         <intent-filter>
    11                                 <data android:mimeType="vnd.android.cursor.item/vnd.ruixin.login" />
    12                         </intent-filter>
    13                          
    14                 </activity>
    15                 <provider android:name="MyProvider" android:authorities="com.ruixin.login" />
    16         </application>
     

    需要在<application></application>中为provider进行注册!!!!
    首先定义一个数据库的工具类:

    01 public class RuiXin {
    02  
    03         public static final String DBNAME = "ruixinonlinedb";
    04         public static final String TNAME = "ruixinonline";
    05         public static final int VERSION = 3;
    06          
    07         public static String TID = "tid";
    08         public static final String EMAIL = "email";
    09         public static final String USERNAME = "username";
    10         public static final String DATE = "date";
    11         public static final String SEX = "sex";
    12          
    13          
    14         public static final String AUTOHORITY = "com.ruixin.login";
    15         public static final int ITEM = 1;
    16         public static final int ITEM_ID = 2;
    17          
    18         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.ruixin.login";
    19         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.ruixin.login";
    20          
    21         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTOHORITY + "/ruixinonline");
    22 }
    1. 然后创建一个数据库:
      01 public class DBlite extends SQLiteOpenHelper {
      02         public DBlite(Context context) {
      03                 super(context, RuiXin.DBNAME, null, RuiXin.VERSION);
      04                 // TODO Auto-generated constructor stub
      05         }
      06         @Override
      07         public void onCreate(SQLiteDatabase db) {
      08                 // TODO Auto-generated method stub
      09                         db.execSQL("create table "+RuiXin.TNAME+"(" +
      10                                 RuiXin.TID+" integer primary key autoincrement not null,"+
      11                                 RuiXin.EMAIL+" text not null," +
      12                                 RuiXin.USERNAME+" text not null," +
      13                                 RuiXin.DATE+" interger not null,"+
      14                                 RuiXin.SEX+" text not null);");
      15         }
      16         @Override
      17         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
      18                 // TODO Auto-generated method stub
      19         }
      20         public void add(String email,String username,String date,String sex){
      21                 SQLiteDatabase db = getWritableDatabase();
      22                 ContentValues values = new ContentValues();
      23                 values.put(RuiXin.EMAIL, email);
      24                 values.put(RuiXin.USERNAME, username);
      25                 values.put(RuiXin.DATE, date);
      26                 values.put(RuiXin.SEX, sex);
      27                 db.insert(RuiXin.TNAME,"",values);
      28         }
      29 }
    1. 接着创建一个Myprovider.java对数据库的接口进行包装:
      001 public class MyProvider extends ContentProvider{
      002  
      003         DBlite dBlite;
      004         SQLiteDatabase db;
      005          
      006         private static final UriMatcher sMatcher;
      007         static{
      008                 sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
      009                 sMatcher.addURI(RuiXin.AUTOHORITY,RuiXin.TNAME, RuiXin.ITEM);
      010                 sMatcher.addURI(RuiXin.AUTOHORITY, RuiXin.TNAME+"/#", RuiXin.ITEM_ID);
      011  
      012         }
      013         @Override
      014         public int delete(Uri uri, String selection, String[] selectionArgs) {
      015                 // TODO Auto-generated method stub
      016                 db = dBlite.getWritableDatabase();
      017                 int count = 0;
      018                 switch (sMatcher.match(uri)) {
      019                 case RuiXin.ITEM:
      020                         count = db.delete(RuiXin.TNAME,selection, selectionArgs);
      021                         break;
      022                 case RuiXin.ITEM_ID:
      023                         String id = uri.getPathSegments().get(1);
      024                         count = db.delete(RuiXin.TID, RuiXin.TID+"="+id+(!TextUtils.isEmpty(RuiXin.TID="?")?"AND("+selection+')':""), selectionArgs);
      025                     break;
      026                 default:
      027                         throw new IllegalArgumentException("Unknown URI"+uri);
      028                 }
      029                 getContext().getContentResolver().notifyChange(uri, null);
      030                 return count;
      031         }
      032  
      033         @Override
      034         public String getType(Uri uri) {
      035                 // TODO Auto-generated method stub
      036                 switch (sMatcher.match(uri)) {
      037                 case RuiXin.ITEM:
      038                         return RuiXin.CONTENT_TYPE;
      039                 case RuiXin.ITEM_ID:
      040                     return RuiXin.CONTENT_ITEM_TYPE;
      041                 default:
      042                         throw new IllegalArgumentException("Unknown URI"+uri);
      043                 }
      044         }
      045  
      046         @Override
      047         public Uri insert(Uri uri, ContentValues values) {
      048                 // TODO Auto-generated method stub
      049                  
      050                 db = dBlite.getWritableDatabase();
      051                 long rowId;
      052                 if(sMatcher.match(uri)!=RuiXin.ITEM){
      053                         throw new IllegalArgumentException("Unknown URI"+uri);
      054                 }
      055                 rowId = db.insert(RuiXin.TNAME,RuiXin.TID,values);
      056                    if(rowId>0){
      057                            Uri noteUri=ContentUris.withAppendedId(RuiXin.CONTENT_URI, rowId);
      058                            getContext().getContentResolver().notifyChange(noteUri, null);
      059                            return noteUri;
      060                    }
      061                    throw new IllegalArgumentException("Unknown URI"+uri);
      062         }
      063  
      064         @Override
      065         public boolean onCreate() {
      066                 // TODO Auto-generated method stub
      067                 this.dBlite = new DBlite(this.getContext());
      068 //                db = dBlite.getWritableDatabase();
      069 //                return (db == null)?false:true;
      070                 return true;
      071         }
      072  
      073         @Override
      074         public Cursor query(Uri uri, String[] projection, String selection,
      075                         String[] selectionArgs, String sortOrder) {
      076                 // TODO Auto-generated method stub
      077                 db = dBlite.getWritableDatabase();               
      078                 Cursor c;
      079                 Log.d("-------", String.valueOf(sMatcher.match(uri)));
      080                 switch (sMatcher.match(uri)) {
      081                 case RuiXin.ITEM:
      082                         c = db.query(RuiXin.TNAME, projection, selection, selectionArgs, nullnullnull);
      083                  
      084                         break;
      085                 case RuiXin.ITEM_ID:
      086                         String id = uri.getPathSegments().get(1);
      087                         c = db.query(RuiXin.TNAME, projection, RuiXin.TID+"="+id+(!TextUtils.isEmpty(selection)?"AND("+selection+')':""),selectionArgs, nullnull, sortOrder);
      088                     break;
      089                 default:
      090                         Log.d("!!!!!!""Unknown URI"+uri);
      091                         throw new IllegalArgumentException("Unknown URI"+uri);
      092                 }
      093                 c.setNotificationUri(getContext().getContentResolver(), uri);
      094                 return c;
      095         }
      096         @Override
      097         public int update(Uri uri, ContentValues values, String selection,
      098                         String[] selectionArgs) {
      099                 // TODO Auto-generated method stub
      100                 return 0;
      101         }
      102 }


      最后创建测试类:
      01 public class Test extends Activity {
      02     /** Called when the activity is first created. */
      03    private DBlite dBlite1 = new DBlite(this);;
      04         private ContentResolver contentResolver;
      05                     public void onCreate(Bundle savedInstanceState) {
      06                 super.onCreate(savedInstanceState);
      07                 setContentView(R.layout.main);
      08                 //先对数据库进行添加数据
      09             dBlite1.add(email,username,date,sex);
      10             //通过contentResolver进行查找
      11              contentResolver = TestWebviewDemo.this.getContentResolver();
      12             Cursor cursor = contentResolver.query(
      13                   RuiXin.CONTENT_URI, new String[] {
      14                   RuiXin.EMAIL, RuiXin.USERNAME,
      15                   RuiXin.DATE,RuiXin.SEX }, nullnullnull);
      16                 while (cursor.moveToNext()) {
      17                      Toast.makeText(
      18                     TestWebviewDemo.this,
      19                     cursor.getString(cursor.getColumnIndex(RuiXin.EMAIL))
      20                             " "
      21                             + cursor.getString(cursor.getColumnIndex(RuiXin.USERNAME))
      22                             " "
      23                             + cursor.getString(cursor.getColumnIndex(RuiXin.DATE))
      24                             " "
      25                             + cursor.getString(cursor.getColumnIndex(RuiXin.SEX)),
      26                            Toast.LENGTH_SHORT).show();
      27                      }
      28                    startManagingCursor(cursor);  //查找后关闭游标
      29             }
      30         }

      注:上面是在一个程序中进行的测试,也可以再新建一个工程来模拟一个新的程序,然后将上面查询的代码加到新的程序当中!这样就模拟了contentprovider的数据共享功能了!
      新建个工程:TestProvider
      创建一个测试的activity
      01 public class Test extends Activity {
      02     /** Called when the activity is first created. */
      03         private ContentResolver contentResolver;
      04                     public void onCreate(Bundle savedInstanceState) {
      05                 super.onCreate(savedInstanceState);
      06                 setContentView(R.layout.main);
      07                
      08             //通过contentResolver进行查找
      09               contentResolver = TestWebviewDemo.this.getContentResolver();                    
      10              Cursor cursor = contentResolver.query(
      11                 RuiXin.CONTENT_URI, new String[] {
      12                 RuiXin.EMAIL, RuiXin.USERNAME,
      13                 RuiXin.DATE,RuiXin.SEX }, nullnullnull);
      14             while (cursor.moveToNext()) {
      15                Toast.makeText(TestWebviewDemo.this,
      16                        cursor.getString(cursor.getColumnIndex(RuiXin.EMAIL))
      17                        " "
      18                        + cursor.getString(cursor.getColumnIndex(RuiXin.USERNAME))
      19                        " "
      20                        + cursor.getString(cursor.getColumnIndex(RuiXin.DATE))
      21                        " "
      22                        + cursor.getString(cursor.getColumnIndex(RuiXin.SEX)),
      23                        Toast.LENGTH_SHORT).show();
      24                    }
      25                    startManagingCursor(cursor);  //查找后关闭游标
      26             }
      27         }
      运行此程序就能实现共享数据查询了!

      注:新建的程序中的manifest.xml中不需要对provider进行注册,直接运行就行,否则会报错!
  • 相关阅读:
    Kubernetes实战:高可用集群的搭建和部署
    华为云MVP程云:知识化转型,最终要赋能一线
    支持60+数据传输链路,华为云DRS链路商用大盘点
    关于单元测试的那些事儿,Mockito 都能帮你解决
    深入原生冰山安全体系,详解华为云安全服务如何构筑全栈安全
    云小课|ModelArts Pro 视觉套件:零代码构建视觉AI应用
    FLINK重点原理与机制:内存(1)task之间的数据传输
    FLINK重点原理与机制:内存(2)网络流控及反压机制剖析(一)
    FLINK重点原理与机制:状态(3)两阶段提交
    FLINK重点原理与机制:状态(2)Flink的检查点算法CHECKPOINT
  • 原文地址:https://www.cnblogs.com/Gaojiecai/p/2233827.html
Copyright © 2011-2022 走看看