Android数据持久化之ContentProvider机制详解

 更新时间:2017年05月02日 14:36:32   作者:android小猪  
这篇文章主要介绍了Android数据持久化之ContentProvider机制,结合实例形式分析了ContentProvider机制的原理与相关使用技巧,需要的朋友可以参考下

本文实例讲述了Android数据持久化之ContentProvider机制。分享给大家供大家参考,具体如下:

一般而言,android操作系统的应用程序所建立的数据只允许自己使用,应用程序彼此间无法借助公用存储器来共享数据,android系统提供了一个机制,即内容提供器(ContentProvider),来公开自己私有的数据到数据内容器,通过该机制,可以供其他应用程序来读取自己内部的数据,当然也可以访问其他应用程序的数据。通常,内容提供器背后都有SQLite数据库的支持,用以存储内容提供内部数据。

实现ContentProvider与实现SQLite的区别:

应用程序实现SQLite时,由应用程序直接与数据库进行对接,所以要在应用程序中实现SQLite的接口:db.onCreate()、db.insert()、db.update()、db.delete()、db.query()和db.close();

实现内容提供器时,在应用程序与数据库之间要实现一个ContentProvider程序,这个ContentProvider程序会直接与数据库进行对接,此时应用程序需要实现和ContentProvider程序接口的方法。

下面该说说如何建立内容提供器了:

首先,实现内容提供器接口:

实现该接口的5个重要方法;

其次,定义数据Uri:

提供器应用程序需要定义一个“基底”Uri,以供其他应用程序访问这一内容提供器,这一个Uri必须是唯一的,且必须是以“content://”开头,content:   表示内容提供器程序所控制数据的位置;在AndroidManifest.xml配置文件中添加如下代码以进行声明:

<!-- 设置类名和授权 multiprocess属性是数据的同步性(同一时间可能有多个程序访问该内容提供器)-->
<provider
  android:name="ContentProviderClass"
  android:multiprocess="true"
  android:authorities="com.example.data_contentprovider.ContentProviderClass" >
</provider>

在应用程序中添加如下代码:

//acquire the Uri of ContentProvider
getIntent().setData(Uri.parse("content://com.example.data_contentprovider.ContentProviderClass"));
Uri uri = getIntent().getData();

定义一个Uri所在的位置,并设置一个变量来找到内容提供器程序的接口;

如下是一个完整的代码,功能是实现内容提供器的建立以及通过该内容提供器程序来添加和检索数据:

实现内容提供器接口的代码:

package com.example.data_contentprovider;
import com.example.data_contentprovider.DB.DBHelper;
import android.net.Uri;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
public class ContentProviderClass extends ContentProvider {
  DBHelper dataBaseHelper; // 定义DataBaseHelper类变量dataBaseHelper
  // 实现ContentProvider的onCreate方法
  @Override
  public boolean onCreate() {
    // TODO Auto-generated method stub
    dataBaseHelper = new DBHelper(getContext());
    return true;
  }
  @Override
  public Uri insert(Uri uri, ContentValues values) {
    // TODO Auto-generated method stub
    SQLiteDatabase db = dataBaseHelper.getWritableDatabase();
    db.insert("test", null, values);
    return null;
  }
  @Override
  public Cursor query(Uri uri, String[] projection, String selection,
      String[] selectionArgs, String sortOrder) {
    // TODO Auto-generated method stub
    SQLiteDatabase db = dataBaseHelper.getReadableDatabase();
    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
    queryBuilder.setTables("test");
    Cursor cursor = queryBuilder.query(db, projection, selection,
        selectionArgs, null, null, null);
    return cursor;
  }
  @Override
  public int delete(Uri uri, String selection, String[] selectionArgs) {
    // TODO Auto-generated method stub
    return 0;
  }
  @Override
  public String getType(Uri uri) {
    // TODO Auto-generated method stub
    return null;
  }
  @Override
  public int update(Uri uri, ContentValues values, String selection,
      String[] selectionArgs) {
    // TODO Auto-generated method stub
    return 0;
  }
}

配置AndroidManifest.xml文件:

<!-- 设置类名和授权 multiprocess属性是数据的同步性(同一时间可能有多个程序访问该内容提供器)-->
<provider
  android:name="ContentProviderClass"
  android:multiprocess="true"
  android:authorities="com.example.data_contentprovider.ContentProviderClass" >
</provider>

建立一个SQLite数据库系统来存储和管理数据,同时利用SQLiteOpenHilper类协助建立数据库和SQLiteDatabase类来管理数据库:

package com.example.data_contentprovider.DB;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;
public class DBHelper extends SQLiteOpenHelper {
  // 建立test.db数据库
  public DBHelper(Context context) {
    super(context, "test.db", null, 1);
  }
  // 建立test表
  @Override
  public void onCreate(SQLiteDatabase db) {
    db.execSQL("create table test (" + BaseColumns._ID
        + "integer primary key," + "name text," + "description text"
        + ");");
  }
  // 更新新版本
  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS test");
    onCreate(db);
  }
}

下面就是provider的应用程序了:

package com.example.data_contentprovider;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class ContentProviderActivity extends Activity {
  String [] from = {"column00","column01","column02"};
  @SuppressWarnings("deprecation")
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    //acquire the Uri of ContentProvider
    getIntent().setData(Uri.parse("content://com.example.data_contentprovider.ContentProviderClass"));
    Uri uri = getIntent().getData();
    //create some data to test
    ContentValues values = new ContentValues();
    values.put("name", "marry");
    values.put("description", "123456");
    getContentResolver().insert(uri, values); //获取ContentResolver对象(在应用程序B中,通过ContentResolver获取程序A的ContentProvider中的数据。)
    values.put("name", "hello");
    values.put("description", "654321");
    getContentResolver().insert(uri, values);
    //search db all colum,cursor point to first colum of result
    Cursor cursor = managedQuery(uri, null, null, null, null);
    cursor.moveToFirst();
    //set ArrayList,view more field table
    ArrayList<Map<String,Object>> data = new ArrayList<Map<String,Object>>();
    Map<String, Object> item;
    //from db read data and save to ArrayList data container
    for (int i = 0; i < cursor.getCount(); i++) {
      item = new HashMap<String, Object>();
      item.put("column00", cursor.getString(0));
      item.put("column01", cursor.getString(1));
      item.put("column02", cursor.getString(2));
      data.add(item);
      cursor.moveToNext();
    }
    cursor.close();
    //ArrayList container data save to listView
    ListView listView = new ListView(this);
    SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.activity_content_provider, from, new int[]{R.id.text1,R.id.text2,R.id.text3});
    listView.setAdapter(adapter);
    setContentView(listView);
  }
}

provider应用程序就可以通过该内容提供器检索数据库并向其添加数据了。

ContentProvider中重要的几个类:

UriMatcher:

要了解UriMatcher,首先需要了解android中的Uri表示方法,众所周知,Uri为通用资源标识符,它代表的是要操作的数据,Android中的每一种资源(比如文本,图像,视频等)都可以用Uri来表示。Android中的Uri由以下三部分组成:”content://”(即authory),数据的路径,资源标识ID(可选),其中如果存在ID,则表示某一个具体的资源,如果不存在ID,则表示路径下的整体。因此addUri()函数的3个参数也是对应上面的那3个。UriMatcher的匹配过程分为3步:初始化UriMatcher;注册需要用的Uri;与已经注册的Uri进行匹配。

ContentResolver :

当使用ContentProvider在不同的应用程序中共享数据时,其数据的暴露方式是采取类似数据库中表的方法。而ContentResolver 是恰好是采用类似数据库的方法来从ContentProvider中存取数据的,它是通过Uri来查询ContentProvider中提供的数据,查询时,还需知道目的数据库的名称,数据段的数据类型,或者说资源的ID。

SQLiteQueryBuilder:

是一个用来生产SQL查询语句的辅助类,可以方便的去访问SQLiteDatabase. 在构造SQL查询语句时,它同样也需要指定表名,指定列名,指定where条件等。

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android资源操作技巧汇总》、《Android编程开发之SD卡操作方法汇总》、《Android文件操作技巧汇总》、《Android数据库操作技巧总结》、《Android编程之activity操作技巧总结》、《Android开发入门与进阶教程》、《Android视图View技巧总结》及《Android控件用法总结

希望本文所述对大家Android程序设计有所帮助。

相关文章

  • Android绘制双折线图的方法

    Android绘制双折线图的方法

    这篇文章主要为大家详细介绍了Android绘制双折线图的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • ShareSDK造成App崩溃的一个BUG原因分析以及Fix方法

    ShareSDK造成App崩溃的一个BUG原因分析以及Fix方法

    这篇文章主要介绍了ShareSDK造成App崩溃的一个BUG原因分析以及Fix方法,使用的是Cocos2d-x专用ShareSDK组件,需要的朋友可以参考下
    2014-04-04
  • android仿即刻点赞文字部分的自定义View的示例代码

    android仿即刻点赞文字部分的自定义View的示例代码

    本篇文章主要介绍了android仿即刻点赞文字部分的自定义View的示例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • Android自定义view绘制表格的方法

    Android自定义view绘制表格的方法

    这篇文章主要为大家详细介绍了Android自定义view绘制表格的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Android编程解析XML方法详解(SAX,DOM与PULL)

    Android编程解析XML方法详解(SAX,DOM与PULL)

    这篇文章主要介绍了Android编程解析XML方法,结合实例形式详细分析了Android解析XML文件的常用方法与相关实现技巧,需要的朋友可以参考下
    2016-01-01
  • android自定义进度条移动效果

    android自定义进度条移动效果

    这篇文章主要为大家详细介绍了android自定义进度条移动效果,进度数字随进度移动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-05-05
  • Android事件与手势操作详解

    Android事件与手势操作详解

    现在程序都是通过事件实现人机交互的。事件:用于对图形界面的操作,有物理按键事件和触摸屏事件两大类。在Android组件中提供了事件处理的相关方法,如在View类中提供onTouchEvent()方法重写触摸屏事件,setOnTouchListener()方法为组件设置监听器来处理触摸屏事件
    2022-12-12
  • Android自定义View仿支付宝芝麻信用分仪表盘

    Android自定义View仿支付宝芝麻信用分仪表盘

    前几天支付宝刚刚升级到v9.9,看了一眼里面的芝麻信用分,仪表盘挺好看的,所以想着来写一个这个版本的仪表盘,不说完全一模一样,只是为了猜测支付宝在做这个的时候是如何设计的,在此记录一下,有需要的可以参考借鉴。
    2016-09-09
  • Android利用CursorLoader实现短信验证码自动填写

    Android利用CursorLoader实现短信验证码自动填写

    这篇文章主要为大家详细介绍了Android利用CursorLoader实现短信验证码自动填写的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • Android RadioButton 图片位置与大小实例详解

    Android RadioButton 图片位置与大小实例详解

    这篇文章主要介绍了Android RadioButton 图片位置与大小实例详解的相关资料,这里提供实例代码及实现效果图,需要的朋友可以参考下
    2016-11-11

最新评论