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中的代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <application android:icon="@drawable/icon" android:label="@string/app_name">
                    <activity android:name=".TestWebviewDemo" android:label="@string/app_name">
                            <intent-filter>
                                    <action android:name="android.intent.action.MAIN" />
                                    <category android:name="android.intent.category.LAUNCHER" />
                            </intent-filter>
                            <intent-filter>
                                    <data android:mimeType="vnd.android.cursor.dir/vnd.ruixin.login" />
                            </intent-filter>
                            <intent-filter>
                                    <data android:mimeType="vnd.android.cursor.item/vnd.ruixin.login" /> 
                            </intent-filter>
                              
                    </activity>
                    <provider android:name="MyProvider" android:authorities="com.ruixin.login" />
            </application>
     

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public class RuiXin {
      
            public static final String DBNAME = "ruixinonlinedb"
            public static final String TNAME = "ruixinonline";
            public static final int VERSION = 3;
              
            public static String TID = "tid";
            public static final String EMAIL = "email";
            public static final String USERNAME = "username";
            public static final String DATE = "date";
            public static final String SEX = "sex";
              
              
            public static final String AUTOHORITY = "com.ruixin.login";
            public static final int ITEM = 1;
            public static final int ITEM_ID = 2;
              
            public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.ruixin.login";
            public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.ruixin.login";
              
            public static final Uri CONTENT_URI = Uri.parse("content://" + AUTOHORITY + "/ruixinonline"); 
    }
    1. 然后创建一个数据库:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      public class DBlite extends SQLiteOpenHelper {
              public DBlite(Context context) {
                      super(context, RuiXin.DBNAME, null, RuiXin.VERSION);
                      // TODO Auto-generated constructor stub
              }
              @Override
              public void onCreate(SQLiteDatabase db) {
                      // TODO Auto-generated method stub
                              db.execSQL("create table "+RuiXin.TNAME+"(" +
                                      RuiXin.TID+" integer primary key autoincrement not null,"
                                      RuiXin.EMAIL+" text not null," +
                                      RuiXin.USERNAME+" text not null," +
                                      RuiXin.DATE+" interger not null,"+
                                      RuiXin.SEX+" text not null);");
              }
              @Override
              public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                      // TODO Auto-generated method stub
              }
              public void add(String email,String username,String date,String sex){
                      SQLiteDatabase db = getWritableDatabase();
                      ContentValues values = new ContentValues();
                      values.put(RuiXin.EMAIL, email);
                      values.put(RuiXin.USERNAME, username);
                      values.put(RuiXin.DATE, date);
                      values.put(RuiXin.SEX, sex);
                      db.insert(RuiXin.TNAME,"",values);
              }
      }
    1. 接着创建一个Myprovider.java对数据库的接口进行包装:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      public class MyProvider extends ContentProvider{
        
              DBlite dBlite;
              SQLiteDatabase db;
                
              private static final UriMatcher sMatcher;
              static{
                      sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
                      sMatcher.addURI(RuiXin.AUTOHORITY,RuiXin.TNAME, RuiXin.ITEM);
                      sMatcher.addURI(RuiXin.AUTOHORITY, RuiXin.TNAME+"/#", RuiXin.ITEM_ID);
        
              }
              @Override
              public int delete(Uri uri, String selection, String[] selectionArgs) {
                      // TODO Auto-generated method stub
                      db = dBlite.getWritableDatabase();
                      int count = 0;
                      switch (sMatcher.match(uri)) {
                      case RuiXin.ITEM:
                              count = db.delete(RuiXin.TNAME,selection, selectionArgs);
                              break;
                      case RuiXin.ITEM_ID:
                              String id = uri.getPathSegments().get(1);
                              count = db.delete(RuiXin.TID, RuiXin.TID+"="+id+(!TextUtils.isEmpty(RuiXin.TID="?")?"AND("+selection+')':""), selectionArgs);
                          break;
                      default:
                              throw new IllegalArgumentException("Unknown URI"+uri);
                      }
                      getContext().getContentResolver().notifyChange(uri, null);
                      return count;
              }
        
              @Override
              public String getType(Uri uri) {
                      // TODO Auto-generated method stub
                      switch (sMatcher.match(uri)) {
                      case RuiXin.ITEM:
                              return RuiXin.CONTENT_TYPE;
                      case RuiXin.ITEM_ID:
                          return RuiXin.CONTENT_ITEM_TYPE;
                      default:
                              throw new IllegalArgumentException("Unknown URI"+uri);
                      }
              }
        
              @Override
              public Uri insert(Uri uri, ContentValues values) {
                      // TODO Auto-generated method stub
                        
                      db = dBlite.getWritableDatabase();
                      long rowId;
                      if(sMatcher.match(uri)!=RuiXin.ITEM){
                              throw new IllegalArgumentException("Unknown URI"+uri);
                      }
                      rowId = db.insert(RuiXin.TNAME,RuiXin.TID,values);
                         if(rowId>0){
                                 Uri noteUri=ContentUris.withAppendedId(RuiXin.CONTENT_URI, rowId);
                                 getContext().getContentResolver().notifyChange(noteUri, null);
                                 return noteUri;
                         }
                         throw new IllegalArgumentException("Unknown URI"+uri);
              }
        
              @Override
              public boolean onCreate() {
                      // TODO Auto-generated method stub
                      this.dBlite = new DBlite(this.getContext());
      //                db = dBlite.getWritableDatabase();
      //                return (db == null)?false:true;
                      return true;
              }
        
              @Override
              public Cursor query(Uri uri, String[] projection, String selection,
                              String[] selectionArgs, String sortOrder) {
                      // TODO Auto-generated method stub
                      db = dBlite.getWritableDatabase();                
                      Cursor c;
                      Log.d("-------", String.valueOf(sMatcher.match(uri)));
                      switch (sMatcher.match(uri)) {
                      case RuiXin.ITEM:
                              c = db.query(RuiXin.TNAME, projection, selection, selectionArgs, nullnullnull);
                        
                              break;
                      case RuiXin.ITEM_ID:
                              String id = uri.getPathSegments().get(1);
                              c = db.query(RuiXin.TNAME, projection, RuiXin.TID+"="+id+(!TextUtils.isEmpty(selection)?"AND("+selection+')':""),selectionArgs, nullnull, sortOrder); 
                          break;
                      default:
                              Log.d("!!!!!!""Unknown URI"+uri);
                              throw new IllegalArgumentException("Unknown URI"+uri);
                      }
                      c.setNotificationUri(getContext().getContentResolver(), uri);
                      return c;
              }
              @Override
              public int update(Uri uri, ContentValues values, String selection,
                              String[] selectionArgs) {
                      // TODO Auto-generated method stub
                      return 0;
              }
      }


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

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

      注:新建的程序中的manifest.xml中不需要对provider进行注册,直接运行就行,否则会报错!
  • 相关阅读:
    hi.baidu.com 百度流量统计
    Autofac is designed to track and dispose of resources for you.
    IIS Manager could not load type for module provider 'SharedConfig' that is declared in administration.config
    How to create and manage configuration backups in Internet Information Services 7.0
    定制swagger的UI
    NSwag在asp.net web api中的使用,基于Global.asax
    NSwag Tutorial: Integrate the NSwag toolchain into your ASP.NET Web API project
    JS变量对象详解
    JS执行上下文(执行环境)详细图解
    JS内存空间详细图解
  • 原文地址:https://www.cnblogs.com/it-tomorrow/p/3342636.html
Copyright © 2011-2022 走看看