热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

Android中ContentProvider和ContentResolver详解

这篇文章主要介绍了Android中ContentProvider和ContentResolver详解的相关资料,需要的朋友可以参考下

Android中ContentProvider和ContentResolver详解

在Android中,我们的应用有的时候需要对外提供数据接口,可以有如下几种方法:

1)AIDL 2)Broadcast 3)ContentProvider。

使用AIDL需要我们编写AIDL接口以及实现,而且对方也要有相应的接口描述,有点麻烦;使用Broadcast,我们不需要任何接口描述,只要协议文档就可以了,但是有点不好就是,这种方式不直接而且是异步的;使用ContentProvider我们不需要接口描述,只需要知道协议,同时这种方式是同步的,使用方便。

下面是ContentProvider实现:

package com.backgroundservice;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.NET.Uri;
import android.util.Log;

/**
 * TODO
 * 
 * @author zengpeng
 * @version 1.0 Create At : 2010-3-18 下午02:52:40
 */
public class TestContentProvider extends ContentProvider {
  private SQLiteDatabase mDb;
  private DatabaseHelper mDbHelper = null;
  private static final String DATABASE_NAME = "rssitems.db";
  private static final String DATABASE_TABLE_NAME = "rssItems";
  private static final int DB_VERSION = 1;
  private static final int ALL_MESSAGES = 1;
  private static final int SPECIFIC_MESSAGE = 2;

  // Set up our URL matchers to help us determine what an
  // incoming URI parameter is.
  private static final UriMatcher URI_MATCHER;
  static {
    URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
    URI_MATCHER.addURI("test", "item", ALL_MESSAGES);
    URI_MATCHER.addURI("test", "item/#", SPECIFIC_MESSAGE);
  }

  // Here's the public URI used to query for RSS items.
  public static final Uri CONTENT_URI = Uri
      .parse("content://test/item");

  // Here are our column name constants, used to query for field values. 

    public static final String ID = "_id";
    public static final String NAME = "NAME";
    public static final String VALUE = "VALUE";
    public static final String DEFAULT_SORT_ORDER = ID + " DESC";

  private static class DatabaseHelper extends AbstractDatabaseHelper {

    @Override
    protected String[] createDBTables() {
      // TODO Auto-generated method stub
      String sql = "CREATE TABLE " + DATABASE_TABLE_NAME + "(" + ID
          + " INTEGER PRIMARY KEY AUTOINCREMENT, " + NAME + " TEXT,"
          + VALUE + " TEXT);";
      return new String[] { sql };
    }

    @Override
    protected String[] dropDBTables() {
      // TODO Auto-generated method stub
      return null;
    }

    @Override
    protected String getDatabaseName() {
      // TODO Auto-generated method stub
      return DATABASE_NAME;
    }

    @Override
    protected int getDatabaseVersion() {
      // TODO Auto-generated method stub
      return DB_VERSION;
    }

    @Override
    protected String getTag() {
      // TODO Auto-generated method stub
      return TestContentProvider.class.getSimpleName();    }

  }

  /**
   * 
   */
  public TestContentProvider() {
    // TODO Auto-generated constructor stub
    
  }

  /*
   * (non-Javadoc)
   * 
   * @see android.content.ContentProvider#delete(android.Net.Uri,
   * Java.lang.String, java.lang.String[])
   */
  @Override
  public int delete(Uri uri, String selection, String[] selectionArgs) {
    // NOTE Argument checking code omitted. Check your parameters!
    int rowCount = mDb.delete(DATABASE_TABLE_NAME, selection, selectionArgs);

    // Notify any listeners and return the deleted row count.
    getContext().getContentResolver().notifyChange(uri, null);
    return rowCount;
  }

  /*
   * (non-Javadoc)
   * 
   * @see android.content.ContentProvider#getType(android.net.Uri)
   */
  @Override
  public String getType(Uri uri) {
    switch (URI_MATCHER.match(uri)) {
    case ALL_MESSAGES:
      return "vnd.android.cursor.dir/rssitem"; // List of items.
    case SPECIFIC_MESSAGE:
      return "vnd.android.cursor.item/rssitem"; // Specific item.
    default:
      return null;
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see android.content.ContentProvider#insert(android.net.Uri,
   * android.content.ContentValues)
   */
  @Override
  public Uri insert(Uri uri, ContentValues values) {
    // NOTE Argument checking code omitted. Check your parameters! Check that
    // your row addition request succeeded!
    long rowId = -1;
    rowId = mDb.insert(DATABASE_TABLE_NAME, NAME, values);
    Uri newUri = Uri.withAppendedPath(CONTENT_URI, ""+rowId);
    Log.i("TestContentProvider", "saved a record " + rowId + " " + newUri);
    // Notify any listeners and return the URI of the new row.
    getContext().getContentResolver().notifyChange(CONTENT_URI, null);
    return newUri;
  }

  /*
   * (non-Javadoc)
   * 
   * @see android.content.ContentProvider#onCreate()
   */
  @Override
  public boolean onCreate() {
    // TODO Auto-generated method stub
    try
    {
      mDbHelper = new DatabaseHelper();
      mDbHelper.open(getContext());
      mDb = mDbHelper.getMDb();
    }catch(Exception e){
      e.printStackTrace();
    }
    return true;
  }

  /*
   * (non-Javadoc)
   * 
   * @see android.content.ContentProvider#query(android.net.Uri,
   * java.lang.String[], java.lang.String, java.lang.String[],
   * java.lang.String)
   */
  public Cursor query(Uri uri, String[] projection, String selection,
      String[] selectionArgs, String sortOrder) {
    // We won't bother checking the validity of params here, but you should!

    // SQLiteQueryBuilder is the helper class that creates the
    // proper SQL syntax for us.
    SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();

    // Set the table we're querying.
    qBuilder.setTables(DATABASE_TABLE_NAME);

    // If the query ends in a specific record number, we're
    // being asked for a specific record, so set the   

    // WHERE clause in our query.
    if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
      qBuilder.appendWhere("_id=" + uri.getLastPathSegment());
      Log.i("TestContentProvider", "_id=" + uri.getLastPathSegment());
    }


    // Make the query.
    Cursor c = qBuilder.query(mDb,
        projection,
        selection,
        selectionArgs,
        null,
        null,
        sortOrder);
    Log.i("TestContentProvider", "get records");
    c.setNotificationUri(getContext().getContentResolver(), uri);
    return c;
  }

  /*
   * (non-Javadoc)
   * 
   * @see android.content.ContentProvider#update(android.net.Uri,
   * android.content.ContentValues, java.lang.String, java.lang.String[])
   */
  @Override
  public int update(Uri uri, ContentValues values, String selection,
      String[] selectionArgs) {
    // NOTE Argument checking code omitted. Check your parameters!
    int updateCount = mDb.update(DATABASE_TABLE_NAME, values, selection, selectionArgs);

    // Notify any listeners and return the updated row count.
    getContext().getContentResolver().notifyChange(uri, null);
    return updateCount;
  }

}

配文件如下:  

 
    

在客户端中可以使用如下方法进行调用:

 ContentValues values = new ContentValues();
        values.put(TestContentProvider.NAME, "testname1");
        values.put(TestContentProvider.VALUE, "testvalu1e");
        Uri newAddUri = TestActivity.this.getContentResolver().insert(TestContentProvider.CONTENT_URI, values);
        Cursor c = TestActivity.this.managedQuery(newAddUri, new String[]{TestContentProvider.NAME}, null, null, null);
        Log.i("TestActivity", "" + c.getCount());
        if(c.moveToNext())
        {
          Log.i("TestActivity", c.getString(0));
        }

上面的代码是先进行插入,然后进行查询并打印。就是如此简单,所有的应用如果需要都可以对外方便的提供数据接口,同时其他应用也可以很方便的进行调用。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


推荐阅读
  • 请看|间隔时间_Postgresql 主从复制 ... [详细]
  • MySQL锁机制详解
    本文深入探讨了MySQL中的锁机制,包括表级锁、行级锁以及元数据锁,通过实例详细解释了各种锁的工作原理及其应用场景。同时,文章还介绍了如何通过锁来优化数据库性能,避免常见的并发问题。 ... [详细]
  • 本文探讨了如何利用SqlDependency执行复杂的SQL查询,并确保在多线程环境下的安全性与效率。 ... [详细]
  • 深入解析Android中的SQLite数据库使用
    本文详细介绍了如何在Android应用中使用SQLite数据库进行数据存储。通过自定义类继承SQLiteOpenHelper,实现数据库的创建与版本管理,并提供了具体的学生信息管理示例代码。 ... [详细]
  • 探讨HTML中的DIV样式难题
    本文深入分析了HTML中常见的DIV样式问题,并提供了有效的解决策略。适合所有对Web前端开发感兴趣的读者。 ... [详细]
  • 本文探讨了天才与疯子之间的微妙界限,介绍了如何利用巨人的工具提升自我,以及如何通过科学决策、数据洞察和智慧的尺度来指导我们的生活和工作。 ... [详细]
  • 本文详细介绍了如何使用Python中的xlwt库将数据库中的数据导出至Excel文件,适合初学者和中级开发者参考。 ... [详细]
  • 前言无论是对于刚入行工作还是已经工作几年的java开发者来说,面试求职始终是你需要直面的一件事情。首先梳理自己的知识体系,针对性准备,会有事半功倍的效果。我们往往会把重点放在技术上 ... [详细]
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • 探讨如何通过SQL查询将来自多个表的多行信息整合到同一行中展示,特别适用于需要汇总特定商品所有相关信息的场景。 ... [详细]
  • 本文旨在详细介绍如何在PL/SQL环境中调试Oracle数据库中的触发器。虽然触发器能够实现某些复杂的功能,但其使用可能增加系统的维护难度。因此,本文不仅提供技术指导,还讨论了触发器使用的利弊。 ... [详细]
  • Mac下 运行Win7虚拟机内SQL Server 2008 Management Studio 如何访问外接移动硬盘 ... [详细]
  • 本文将详细介绍如何在ThinkPHP6框架中实现多数据库的部署,包括读写分离的策略,以及如何通过负载均衡和MySQL同步技术优化数据库性能。 ... [详细]
  • 本文将深入探讨如何使用 SQLAlchemy 在数据库模型中定义和操作不同类型的表间关系,包括一对一、一对多及多对多的关系。 ... [详细]
  • 迎接云数据库新时代:程序员如何应对变革?
    在数据无处不在的时代,数据库成为了管理和处理数据的核心工具。从早期的信息记录方式到现代的云数据库,数据库技术经历了巨大的变革。本文将探讨云数据库的特点及其对程序员的影响。 ... [详细]
author-avatar
最棒小小丫_635
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有