SQLiteDatabase和Contentprovider这两个数据库,我一般是用前面一个,喜欢它的操作数据库的语句,简单明了,可惜有时遇到数据库同步的问题,有时我们需要在一个数据库下建立多个表,多个Activity都要访问到数据库。最近就遇到过这个问题,虽然应用没有死掉,但有时报错也不太爽,报的警告如下

A SQLiteConnection object for database '/storage/sdcard0/vpnmsgdb.db' was leaked!  Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.

不过虽然警告是报了,我暂时也没有改,虽然Contentprovider这个接口可以解决同步的问题,也许是一直都是用SQLiteDatabase的原因吧,个人觉得只要应用不死掉应该问题不大,

在网上找到有Contentprovider的例子。

原文在http://www.cnblogs.com/chenglong/articles/1892029.html

贴上原文

一、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,
    null
    ,
    null
    ,
    null
    );
                     
                            
    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,
    null
    ,
    null
    , 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 },
    null
    ,
    null
    ,
    null
    );
                    
    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 },
    null
    ,
    null
    ,
    null
    );
                
    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进行注册,直接运行就行,否则会报错!

SQLiteDatabase和Contentprovider的更多相关文章

  1. (转)Android学习进阶路线导航线路(Android源码分享)

     转载请注明出处:http://blog.csdn.net/qinjuning 前言:公司最近来了很多应届实习生,看着他们充满信心但略带稚气的脸庞上,想到了去年的自己,那是的我是不是也和 现在的他们一 ...

  2. Android学习进阶路线导航线路(Android源码分享)

                                                                                                       转 ...

  3. 如何学习Android系统源码(转)

    一. Android系统的源代码非常庞大和复杂,我们不能贸然进入,否则很容易在里面迷入方向,进而失去研究它的信心.我们应该在分析它的源代码之前学习好一些理论知识,下面就介绍一些与Android系统相关 ...

  4. Android中个人推崇的数据库使用方式

    手机应用开发中常常会使用到数据库存储一些资料或者进行数据缓存,android中为我们提供了一个轻量的数据库.在上层进行了一层封装,同一时候还为我们提供了ContentProvider的框架.方便我们进 ...

  5. Android Cursor浅析

    1. 本文目的 Android ContentProvider提供了进程间数据交换的一种机制.而数据库的查询就是这样的机制的应用.那么app通过Uri查询数据库而得到的Cursor到底是个什么东西?为 ...

  6. Android之ContentProvider数据存储

    一.ContentProvider保存数据介绍 一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据完全暴露出去,而且ContentProvider是以类似数据库中表的方式将数 ...

  7. Xamarin.Android之ContentProvider

    一.前言 掌握了如何使用SQLiteOpenHelper之后,我们就可以进行下一步的学习.本章我们将会学习如何使用ContentProvider来将数据库方面的操作封装起来,同时它还可以供其他应用访问 ...

  8. ContentProvider域名替换小工具

    开发项目域名想怎么换就怎么换,就是这么任性! 这是一个很有意思的小工具! 这是一个方便开发人员和测试人员的小工具!! 吐槽: 一直在做Android开发,一直总有一个问题存在:做自己公司的apk开发时 ...

  9. 简单的学习心得:网易云课堂Android开发第六章SQLite与ContentProvider

    一.SQLite 1.基本操作: (1)创建数据库:在SQLiteOpenHelper的子类构造器中创建. (2)创建表:在SQLiteOpenHelper的子类onCreate方法中,调用execS ...

随机推荐

  1. Boost Thread学习笔记四

    barrierbarrier类的接口定义如下:  1 class barrier : private boost::noncopyable   // Exposition only 2 { 3 pub ...

  2. javascript (十二)对象二

    JavaScript 中的所有事物都是对象:字符串.数字.数组.日期,等等. 在 JavaScript 中,对象是拥有属性和方法的数据. 属性和方法 属性是与对象相关的值. 方法是能够在对象上执行的动 ...

  3. Qt之启动外部程序(使用参数很全面,还使用了setProcessChannelMode)

    简述 QProcess可以用来启动外部程序,并与它们交互. 要启动一个进程,通过调用start()来进行,参数包含程序的名称和命令行参数,参数作为一个QStringList的单个字符串. 另外,也可以 ...

  4. Delphi 中TWebBrowser的扩展控件TExWebBrowser

    主要扩展了3D界面.右键菜单.是否显示图片.是否支持JAVA等功能. 代码如下: unit ExtWebBrowser; interface uses Windows, SysUtils, Class ...

  5. 14.4.7 Configuring the Number of Background InnoDB IO Threads 配置 后台InnoDB IO Threads的数量

    14.4.7 Configuring the Number of Background InnoDB IO Threads 配置 后台InnoDB IO Threads的数量 InnoDB 使用bac ...

  6. JDK动态代理简单小程序

    Jdk动态代理 1.动态代理使用的情况:需要在多个方法上加上相同的逻辑的时候,需要用到动态代理. 原因:在多个方法上写相同的逻辑,第一费事,第二在不用的时候维护麻烦 使用动态代理需要用到两个类:分别为 ...

  7. 五、Linux/UNIX操作命令积累【cp、mv、cat、grep、ps】

    在使用Linux/UNIX下,常常会使用文本界面去设置系统或操作系统,作者本人在工作的过程也在不断接触这方面的命令,所以为此特酝酿.准备.開始了本文的编写.本文主要记录自己平时遇到的一些Linux/U ...

  8. 二分查找(非递归JAVA)

    庞果网编程英雄会上做的一道题:二分查找(非递归),和大家分享一下: public class BinarySearchClass { public static int binary_search(i ...

  9. JavaFX2: 鼠标拖动选择和Ctrl+Shift连续区间选择的ListView

    JavaFX2的ListView中的多选没有提供鼠标拖动选择的功能,同时按下Ctrl和Shift后连续的区间选中也不支持,以下代码用于处理这两个问题,细节见代码注释: import com.sun.j ...

  10. C#向并口设备发送指令以获取并口设备的状态

    using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; usi ...