ContentProvider学习笔记

  上一章节我们编写了自定义的一个StudentProvider,他提供了两种供外界访问数据的方式,content://come.demo.sqlite.studentprovider/t_student和content://come.demo.sqlite.studentprovider/t_student/#,这一章我们将讲解其他应用程序将如何来访问StudentProvider中的数据。

1、ContentResolver类介绍

  我们知道StudentProvider继承了ContentProvider类,并实现了insert(),update(),delete(),query(),getType()等方法,同样的ContentResolver这个类也提供了insert(),update(),delete(),query()方法,当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法

  ContentResolver 类提供了与ContentProvider类相同签名的四个方法:
    public Uri insert(Uri uri, ContentValues values):该方法用于往ContentProvider添加数据。
    public int delete(Uri uri, String selection, String[] selectionArgs):该方法用于从ContentProvider删除数据。
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):该方法用于更新ContentProvider中的数据。
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):该方法用于从ContentProvider中获取数据。

2、实例:对数据库表t_student的增删改查操作

(1)布局文件main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <Button
android:id="@+id/btnAdd1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="插入数据1"
/> <Button
android:id="@+id/btnAdd2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="插入数据2"
/> <Button
android:id="@+id/btnSearch1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="查询数据1"
/> <Button
android:id="@+id/btnSearch2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="查询数据2"
/> <Button
android:id="@+id/btnUpdate1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="修改数据1"
/> <Button
android:id="@+id/btnUpdate2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="修改数据2"
/> <Button
android:id="@+id/btnDelete1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="删除数据1"
/> <Button
android:id="@+id/btnDelete2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="删除数据2"
/> </LinearLayout>

(2)MainActivity来实现具体的操作

package com.demo.contentprovider;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast; /**
* 使用ContentResolver实现对数据库表t_student的操作
* @author yinbenyang
*/
public class MainActivity extends Activity { private Button btnAdd1, btnAdd2, btnSearch1, btnSearch2, btnUpdate1,
btnUpdate2, btnDelete1, btnDelete2; //匹配content://come.demo.sqlite.studentprovider/t_student路径
private static final int ONE = 1;
//匹配content://come.demo.sqlite.studentprovider/t_student/
private static final int TWO = 2;
//日志输出
private static final String TAG = "ContentProvider";
//定义的一个Uri,这个是StudentProvider提供的一个内容提供者
private static String CONTENT_URI = "content://come.demo.sqlite.studentprovider/t_student"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnAdd1 = (Button) findViewById(R.id.btnAdd1);
btnAdd2 = (Button) findViewById(R.id.btnAdd2);
btnUpdate1 = (Button) findViewById(R.id.btnUpdate1);
btnUpdate2 = (Button) findViewById(R.id.btnUpdate2);
btnSearch1 = (Button) findViewById(R.id.btnSearch1);
btnSearch2 = (Button) findViewById(R.id.btnSearch2);
btnDelete1 = (Button) findViewById(R.id.btnDelete1);
btnDelete2 = (Button) findViewById(R.id.btnDelete2); btnAdd1.setOnClickListener(listener);
btnAdd2.setOnClickListener(listener);
btnUpdate1.setOnClickListener(listener);
btnUpdate2.setOnClickListener(listener);
btnSearch1.setOnClickListener(listener);
btnSearch2.setOnClickListener(listener);
btnDelete1.setOnClickListener(listener);
btnDelete2.setOnClickListener(listener);
} private OnClickListener listener = new OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnAdd1:
add(ONE);
break;
case R.id.btnAdd2:
add(TWO);
break;
case R.id.btnUpdate1:
update(ONE);
break;
case R.id.btnUpdate2:
update(TWO);
break;
case R.id.btnDelete1:
delete(ONE);
break;
case R.id.btnDelete2:
delete(TWO);
break;
case R.id.btnSearch1:
search(ONE);
break;
case R.id.btnSearch2:
search(TWO);
break;
default:
break;
}
}
}; // 查询数据
private void search(int type) {
ContentResolver resolver = getContentResolver();
Uri url = null;
// 指定查询的列名
String projection[] = new String[] { "sid", "sname", "age" };
// 查询的条件
String selection = "";
// 查询条件的参数值
String[] selectionArgs = null;
// 指定是否排序以及使用排序是时的排序规则
String sortOrder = "";
// 查询结果为一个Cursor
Cursor cursor = null;
switch (type) {
case ONE:
// parse方法通过传入一个字符串来构造一个Uri对象
url = Uri.parse(CONTENT_URI);
selection = "sid < ?";
selectionArgs = new String[] { "3" };
cursor = resolver.query(url, projection, selection, selectionArgs,
sortOrder);
while (cursor.moveToNext()) {
Log.i(TAG,
"sid=" + cursor.getInt(0) + ",sname="
+ cursor.getString(1) + ",age="
+ cursor.getShort(2));
Toast.makeText(
this,
"sid=" + cursor.getInt(0) + ",sname="
+ cursor.getString(1) + ",age="
+ cursor.getShort(2), Toast.LENGTH_SHORT)
.show();
}
break;
case TWO:
// 此时指定查询id为1的学生信息
url = ContentUris.withAppendedId(Uri.parse(CONTENT_URI),1);
selection = null;
cursor = resolver.query(url, projection, selection, selectionArgs,
sortOrder);
while (cursor.moveToNext()) {
Log.i(TAG,
"sid=" + cursor.getInt(0) + ",sname="
+ cursor.getString(1) + ",age="
+ cursor.getShort(2));
Toast.makeText(
this,
"sid=" + cursor.getInt(0) + ",sname="
+ cursor.getString(1) + ",age="
+ cursor.getShort(2), Toast.LENGTH_SHORT)
.show();
}
break;
default:
break;
}
} // 删除数据
private void delete(int type) {
ContentResolver resolver = getContentResolver();
Uri url = null;
String where = "";
String[] selectionArgs = null;
switch (type) {
case ONE:
url = Uri.parse(CONTENT_URI);
// 指定删除id为1,2的学生信息
where = "sid in(?,?)";
selectionArgs = new String[] { "1", "2" };
resolver.delete(url, where, selectionArgs);
break;
case TWO:
// 指定删除id为3的学生信息
url = ContentUris.withAppendedId(Uri.parse(CONTENT_URI),3);
Log.i(TAG, "url:" + url);
where = null;
resolver.delete(url, where, selectionArgs);
break;
default:
break;
}
} // 修改数据
private void update(int type) {
ContentResolver resolver = getContentResolver();
ContentValues values = new ContentValues();
Uri url = null;
String where = "";
String[] selectionArgs = null;
switch (type) {
case ONE:
url = Uri.parse(CONTENT_URI);
values.put("sname", "update1");
values.put("age", 22);
where = "sid = ?"; // 指定更新语句的条件(此时若不指定则是更新全部的数据)
selectionArgs = new String[] { "1" }; // 指定占位符的数值
Log.i(TAG, resolver.update(url, values, where, selectionArgs) + "");
break;
case TWO:
// 此时的Uri中包含了需要更新数据的id,所以不再需要指定更新语句的条件和参数值
url = ContentUris.withAppendedId(Uri.parse(CONTENT_URI),2);
values.put("sname", "update2");
values.put("age", 22);
where = null;
Log.i(TAG, resolver.update(url, values, where, selectionArgs) + "");
break;
default:
break;
}
} // 插入数据
private void add(int type) {
ContentResolver resolver = getContentResolver();
ContentValues values = new ContentValues();
values.put("sname", "zhaobenshan");
values.put("age", 23);
Uri url = null;
switch (type) {
case ONE:
url = Uri.parse(CONTENT_URI);
// insert()方法返回一个Uri对象,这个对象是新插入的数据的Uri
Log.i(TAG, resolver.insert(url, values).toString());
break;
case TWO:
/**
* 这个构造一个Uri为:content://com.demo.contentprovider.studentprovider/
* t_student/1,然后插入,实际上新插入的一条数据的id并不会为1,
* 因为已经存在为1的数据了,所以这个和上面的写法一样,生成的数据的id为2
*/
url = ContentUris.withAppendedId(Uri.parse(CONTENT_URI),1);
// insert()方法返回一个Uri对象,这个对象是新插入的数据的Uri
Log.i(TAG, resolver.insert(url, values).toString());
break;
default:
break;
}
}
}

页面显示的布局效果:

而后我们还是利用命令去com.demo.sqlite.activity/database/data.db中查看t_student表

(1) 点击插入数据1或者插入数据2,查看数据:

(2)点击查询数据1,可以看到弹出了id为1和2的两条数据,点击查询数据2可以看到只弹出id为1的数据

(3)点击修改数据1将t_student表中sid为1的name改为update1,age改为22,点击修改数据2将sid为2的name改为update2,age改为22.

(4)点击删除数据1将id为1,2的学生信息删除:如图删除后只剩下id为3的学生信息

  点击删除数据2将id为3的学生信息删除,如图,最后t_student表中已经没有学生信息了

后记:t_student表是SqliteDemo应用程序中的表数据,而现在通过ContentProviderDemo程序也可以实现对t_student表的操作,由此可见,我们的ContentProvider实现数据在应用程序间的共享了

android四大组件之ContentProvider(二)的更多相关文章

  1. Android 四大组件之" ContentProvider "

    前言 ContentProvider作为Android的四大组件之一,是属于需要掌握的基础知识,可能在我们的应用中,对于Activity和Service这两个组件用的很常见,了解的也很多,但是对Con ...

  2. 【Android开发日记】之入门篇(九)——Android四大组件之ContentProvider

    数据源组件ContentProvider与其他组件不同,数据源组件并不包括特定的功能逻辑.它只是负责为应用提供数据访问的接口.Android内置的许多数据都是使用ContentProvider形式,供 ...

  3. Android四大组件之——ContentProvider(一)

    Android四大组件之--ContentProvider(一) 本人邮箱:JohnTsai.Work@gmail.com,欢迎交流讨论. 欢迎转载,转载请注明网址:http://www.cnblog ...

  4. 初学android:四大组件之contentprovider

    一.ContentProvider的概念ContentProvider:为存储和获取数据提供统一的接口.可以在不同的应用程序之间共享数据.Android已经为常见的一些数据提供了默认的ContentP ...

  5. android四大组件之ContentProvider(一)

    ContentProvider学习笔记 1. ContentProvider基本概念 ContentProvider向我们提供了我们在应用程序之间共享数据的一种机制,虽然采用文件和SharedPref ...

  6. Android四大组件之contentProvider

    Activity,Service,broadcast and Contentprovider android 4 大组件. ContentProvider:使用: public class Image ...

  7. Android四大组件之ContentProvider(二)读取设备上的图片、音频和视频

    Android系统提供了MediaScanner,MediaProvider,MediaStore等接口,通过Content Provider的方式提供给用户.当设备开机或者有SD卡插拔等事件发生时, ...

  8. Android四大组件之——ContentProvider(二)

    Content Resolver介绍: 开发者文档中这么定义的: This class provides applications access to the content model. 这个类为应 ...

  9. Android 四大组件之四(ContentProvider)

    ContentProvider调用关系: ContentProvider(数据提供者)是应用程序之间共享数据的一种接口机制,是一种更为高级的数据共享方法. ContentProvider可以指定需要共 ...

随机推荐

  1. 由两点坐标如何画出直线 matlab

    由两点坐标如何画出直线  方法1:利用直线方程 斜率加截距 方法2:数据拟合 %由两点坐标得数据拟合直线与画线 x = [,]; y = [,]; k = ((-)/(-));% 由两点坐标得到直线斜 ...

  2. Java内存分配

    概述 对从事C和C++的程序员来说,在内存管理方面,他们既是拥有最高权利的人,也是从事最基础工作的“劳动人民”. 而对于Java程序员来说,JVM自动进行内存管理,程序员不再需要为每一个new操作去写 ...

  3. Solr整合中文分词组件IKAnalyzer

    我用的Solr是4.10版本, 在csdn下载这个版本的IKAnalyzer:IK Analyzer 2012FF_hf1.zip 解压后目录如下: (1)这里还用solr自带的example实验分词 ...

  4. Rhel6-mpich2 hpc集群配置文档

    系统环境: rhel6 x86_64 iptables and selinux disabled 主机: 192.168.122.121 server21.example.com 192.168.12 ...

  5. c/c++面试题(5)(c++重要的概念详解)

    1.C++面向对象的三大特征? 1)封装:将客观事物封装成抽象的类,并且设计者可以对类的成员进行访问控制权限控制. 这样一方面可以做到数据的隐藏,保护数据安全;另一方面,封装可以修改类的内部 实现而不 ...

  6. Android Studio下SQLite数据库的配置与使用(完)

    一,AS开发app用,所用的数据库有限制,必须使用较小的SQLite(MySql和Sql Server想想就不显示) 但是该数据库并不需要我们单独下载,安装的SDK中已经有了,在C:\AndroidS ...

  7. Winform基础知识

    1.关于登陆部分 this.DialogResult = DialogResult.OK; this.Close(); FrmLogin login = new FrmLogin(m_CurUser) ...

  8. Libgdx 开发指南(1.1) 应用框架——生命周期

    生命周期 Libgdx应用有一个定义好的生命周期,控制着整个应用的状态,例如creation, pausing, resuming, disposing ApplicationListener 开发者 ...

  9. JMeter学习(十)内存溢出解决方法

    使用jmeter进行压力测试时遇到一段时间后报内存溢出outfmenmory错误,导致jmeter卡死了,先尝试在jmeter.bat中增加了JVM_ARGS="-Xmx2048m -Xms ...

  10. RedHat5配置网卡

    RedHat5配置网卡过程: 1.vi /etc/sysconfig/network-scripts/ifcfg-eth0 2.将hdcp修改成static 3.最后添加 IPADDR=192.168 ...