Android基础学习之Provider(内容提供器)

Provider是Android四大组件之一,是一种数据共享机制(封装数据的接口规范)。是一个数据库的代理,实现跨应用间的数据共享,类似于window服务本身不负责启动和关闭,多个应用可同时访问统一provider。

主要类:
ContentProvider 类
ContentProvider 对象将程序内部数据向其他程序公开
ContentResolver 类
其他程序通过ContentResolver 对象对程序内部数据进行CRUD操作

ContentProvider 分类:
1.使用别人的provider 比如电话本,短信,媒体 这些数据系统底层使用xxx.db数据库封装为ContentProvider 接口
2.应用创建的provider 程序员自定义的,可提供给别人使用

如何定义自己的provider
步骤:
1.继承ContentProvider 定义子类
2.重写6个方法(所有方法都需要uri,每个ContentProvider 都提供对外公共uri) ContentProvider 将共享数据定义为uri

public class MenusProvider extends ContentProvider{
   

    @Override
    public boolean onCreate() {
        // 底层数据库初始化
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        return null;
    }

    @Override //要实现该方法必须完成
    //1.定义MIME类型
    //2.定义URI字符串
    //3.用urimather建立code和uri映射
    //4.用code来映射不同MIEM类型    
    public String getType(Uri uri) {
        // 返回MIME类型,一般用静态块来完成
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        return 0;
    }
}

uri代表地址,解决如何表示数据的问题.

3.声明CONTENT_URI公共的静态常量,实现UriMathcer的绑定
当自定义provider需要告诉使用ContentProvider 的人用到那些uri
UriMatcher类 将uri和MIME绑定的
ContentUris类 将uri解析/生成

4.实现provider底层封装到sqlite框架中.
4.1 onCreat() 初始化数据库 SQLiteOpenHelper辅助类
4.2 provider重写提供CRUD操作方法,如何使用uri

如:
content://myfs.pub.menusprovider/menus/2
list={“menus”,”2”}

5.注册provider,在AndroidManifest.xml文件< application>< /application>标签中(四大组件都需要注册)

<provider 
            android:name="com.robin.myprovider.MenusProvider"
            <!--Provider子类全名 -->
            android:authorities="myfs.pub.menusprovider" 
            <!--指定授权者(自定义字符串) -->
            android:exported="true"
            <!-- 跨应用共享数据 设置为true默认为false
            表示该provider能够被其他应用程序组件调用 -->
 >< /provider>

6.测试provider
本地测试provider
远程测试provider

报错:
Installation error: INSTALL_FAILED_CONFLICTING_PROVIDER
表示系统中已经有同名的provider,调试时卸载重装即可。

使用->观察者模式
作用:监听ContentProvider 数据改变
ContentObserver 类
当ContentProvider 共享出来后,有时应用需要实时获得ContentProvider 共享数据的变化需要利用ContentObserver对象来实现。

实现步骤:
1.provider端的CRUD操作改变数据时调用resolver. notifyChange()方法
2.使用provider端要注册ContentObserver 对象
2.1 定义ContentObserver 子类重写onChange(boolean selfChange)方法
2.2 构造子类对象并注册给使用provider端的ContentResolver对象

如:cr.registerContentObserver(Menus.CONTENT_URI, notifyForDescendents, observer);
参数:
Menus.CONTENT_URI:监听CP的uri –> content://authority/menus
notifyForDescendents:true 表示该uri下所有的数据变化都监听
observer:false 表示只是监听uri数据变化

示例:
1.定义数据bean类
文件名Menus.java

package com.ql.providerdemo;

import android.net.Uri;

/**
 * 定义provider需要的相关数据  MIME类型
 * @author qinlang
 *
 */
public class Menus {
   
    // 以下定义provider的MIME类型常量
    public static final String MIME_DIR_PREFIX = "vnd.android.cursor.dir";// MIME类型 多条 
    public static final String MIME_ITEM_PREFIX = "vnd.android.cursor.item";// 单条
    //以上两条为android规定的
    public static final String MIME_ITEM = "vnd.pub.menus";// 自定义MIME类型字符串
    // 将固定前缀+自定义字符串生成两个类型
    public static final String MIME_TYPE_SINGLE = MIME_ITEM_PREFIX + "/"
            + MIME_ITEM;
    public static final String MIME_TYPE_MULTIPLE = MIME_DIR_PREFIX + "/"
            + MIME_ITEM;

    // 用来定义uri常量 content://<authority>/<data path>/..../id
    public static final String AUTHORITY = "myfs.pub.menusprovider";// 授权者 表示用哪个provider,要跟清单文件中一致
    public static final String PATH_SINGLE = "menus/#"; // (menus:数据库表名)路径下单条记录 #代表数字id
    public static final String PATH_MULTIPLE = "menus";// 路径下多条记录 数据库将对应表名
    public static final String PATH_MULTIPLE_NAME = "menus/*"; // *代表文本 例如按名称访问等

    // 组合成所需要的uri字符串
    public static final String CONTENT_URI_STRING = "content://" + AUTHORITY
            + "/" + PATH_MULTIPLE;
    // 将uri字符串转换为uri对象
    public static final Uri CONTENT_URI = Uri.parse(CONTENT_URI_STRING);
    // 以上就完成自定义provider所需的uri和MIME类型的定义

    // 涉及sqlite底层实现的内容
    public static final String CREAT_TABLE = "create table menus(id integer primary key autoincrement ,name varchar(50),price integer)";
    public static final String DBNAME = "pub.db";//数据库名
    public static final String TABLENAME = "menus";//表名
    public static final int DB_VER = 1;//数据库版本,用于升级用

    //常量字符串,对应数据库中的字段
    public static final String KEY_ID = "id";
    public static final String KEY_NAME = "name";
    public static final String KEY_PRICE = "price";

    public static final String[] COLUNMS = { KEY_ID, KEY_NAME, KEY_PRICE };

    private int id;
    private String name;
    private int price;

    public Menus() {
    }

    public Menus(String name, int price) {
        this.name = name;
        this.price = price;
    }

    @Override
    public String toString() {
        return "id:" + id + " | name:" + name + " | price:" + price;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}

2.创建ContentProvider的子类,内容提供类
文件名:MenusProvider.java

package com.ql.providerdemo;

import android.content.ContentProvider;
import android.content.ContentUris;
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自主学习项目报告(一) 1. 自主学习项目要求 1. 收集编写代码过程中碰到的bug,说明bug发生的原因及解决方案 2. 自己在学习过程中总结的知识点 3. 上课内容之外自学的知识点 2. 自主学习内容 按照上面的要求列出至少10条 收集编写代码过程中碰到的bug,说明bug发生的原因及解决方案 (1)使用actionProvider时出现的问题: 解决方案:换一种import的方式即可,如下所示: "1 "//import android.support.v4.view.ActionProvider; " "2 "import android.view.ActionProvider; " (2)Fragment Transactions 和Activity状态丢失 Fragment transactions用于在一个Activity上添加、移除或者替换fragment。大多数时候,frag ment transaction会在activity的onCreate()方法中执行,也可能在与用户交互中响应。 然而,BUG是当恢复一个activity时,fragment transaction被执行了,应用就可能发生下面的下崩溃: 原因:不管何时,如果一个FragmentActivity放在后台,对应FragmentMangerI mpl中mStateSaved的flag就会设置为true。这个flag是用来检查是否有state loss。 当试图执行一个transaction时,如果这个flag为true,那么就首先会抛出IllegalSt ateException异常。 解决方案:不要在让transactions在其他的Activity生命周期函数提交,如onActivi tyResult()、onStart()和onResume() 自己在学习过程中总结的知识点 (3)Android体系结构和Android项目目录 Android是基于Linux内核的软件平台和操作系统,采用了软件堆栈的架构,共分为4 层:第一层是Linux内核,提供由操作系统内核管理的底层基础功能;第二层是中间件层 ,由函数库和Android运行时构成;第三层是应用程序框架层,提供Android平台基本 的管理功能和组件重用机制;第四层是应用程序层,提供了一系列核心应用程序。 src 源代码目录 gen 目录(R.java文件是ADT自动生成,不能手动修改,R.java作用:src中的代码通过R.ja va访问res中的资源) res 资源目录(/res/layout/目录:界面布局文件,xml;/res/raw不参加编译的资源,不能生 成对应文件) AndroidManifest.xml 清单文件(声明应用程序属性信息,声明组件,声明权限,唯一一个组件BroadcastRec eiver不需在AndroidManifest中注册) (4)四大组件及其常用界面布局: Activity是app的表示层,作用:与用户交互,显示信息;Service用于无用户界面, 但需长时间在后台运行的应用;BroadcastReceiver监听系统广播、其它应用程序广播、 其它组件广播,并响应广播消息;ContentProvider用于进程间共享数据。 线性布局---LinearLayout 表格布局---TableLayout 相对布局---RelativeLayout 帧布局---FrameLayout 网格布局---GridLayout 绝对布局---AbsoluteLayout (5)Activity的两种启动方式、四种状态、四种模式 直接启动 :startActivity(Intent intent) 带返回值启动:startActivityForResult(Intent intent, int requestCode) onCreate()、onStart()、onRestart()、onResume()、onPause()、onSt op()、onDestroy() Activity4种状态: 运行状态:Activity位于前台,用户可见,获得焦点 暂停状态: Activity可见,但被其它Activity覆盖,没有获得焦点 停止状态:不可见,失去焦点 销毁状态:Activity结束,或所在进程被结束 Activity有4种启动模式,分别为standard、singleTop、singleTask和singleInsta nce (6)Intent的启动方式及其七大属性 显式Intent(指定启动名称): 明确指出目标组件名称的Intent 告诉Android系统,我要"找谁",Android平台将目标组件启动起来 常用于APP内部组件间启动 隐式Inten
下载一个cebx阅读即可 《Android高薪之路:Android程序员面试宝典》目录: 第1章 Android入门 1 1 关于Android的非技术问题 1 1 1 为什么看好 Android 1 1 2 以前是否从事过Android的工作 做过哪些工作 1 1 3 你做的最复杂的界面是什么 1 1 4 如何解决Android学习中遇到的难题 1 1 5 Android只能在手机或其他移动设备上使用吗 1 2 Android的基本概念 1 2 1 Android的特点都有哪些 1 2 2 MVC模式 1 2 3 Android 的系统构架 1 3 开发Android应用程序 1 3 1 搭建Android开发环境 1 3 2 Android开发环境的使用 第2章 布局 2 1 Android中的布局 2 2 布局使用技巧 2 2 1 FrameLayout布局 2 2 2 LinearLayout布局 2 2 3 RelativeLayout布局 2 2 4 TableLayout布局 2 2 5 AbsoluteLayout布局 2 2 6 将布局存成图像 2 2 7 设置渐变背景色 2 3 布局属性 2 3 1 android:layout weight属性 2 3 2 android:padding属性和android:layout margin属性 2 3 3 android:layout gravity属性和android:gravity属性 2 4 高级布局技术 第3章 组件 3 1 组件的属性 3 2 文本组件 3 3 按钮组件 3 4 图像组件 3 5 进度组件 3 6 列表组件 3 7 容组件 3 8 自定义组件 3 9 四大应用程序组件 3 9 1 Android中的窗口:Activity 3 9 2 广播接收:Broadcast Receiver 3 9 3 服务 Service 3 9 4 内容提供者 Content Provider 第4章 对话框 信息提示和菜单 4 1 对话框 4 2 信息提示 4 2 1 Toast信息框 4 2 2 通知 Notification 4 3 菜单 第5章 文件存储 5 1 SharedPreferences 5 2 流文件 5 3 XML存储 5 4 JSON存储 第6章 数据库 6 1 SQLite基础知识 6 2 SQLite 函数 6 2 1 核心函数 6 2 2 日期和时间函数 6 2 3 聚合函数 6 3 在Android中使用SQLite 6 4 面向对象数据库:db4o 第7章 网络与加密 7 1 客户端Socket 7 2 服务端Socket 7 3 非阻塞I O 7 4 WebView控件 7 5 HTTP和HTTPS 7 6 加密技术 第8章 蓝牙与Wi Fi 8 1 蓝牙 8 2 Wi Fi 第9章 电话 短信和联系人 9 1 来电和回电 9 2 短信 9 3 彩信 9 4 联系人 第10章 多媒体技术 10 1 音频 10 2 视频 10 3 摄像头 10 4 铃声 第11章 2D绘图与动画技术 11 1 绘制基本图形 11 2 图像特效 11 3 路径 11 4 帧 Frame 动画 11 5 补间 Tween 动画 第12章 OpenGL ES 12 1 OpenGL ES简介 12 2 理解3D坐标系:照相机原理 12 3 如何使用OpenGL ES绘制图形 12 4 绘制2D图形 12 5 绘制3D图形 12 6 光照效果 第13章 Android系统的资源 13 1 资源的基础问题 13 2 本地化 13 3 字符串资源 13 4 布局资源 13 5 图像资源 13 6 其他资源 第14章 其他面试例题 14 1 NDK编程 14 2 传感 14 3 语音识别技术 14 4 Google地图与GPS 14 5 桌面插件 14 6 输入法开发 14 7 测试驱动开发 14 8 性能优化">下载一个cebx阅读即可 《Android高薪之路:Android程序员面试宝典》目录: 第1章 Android入门 1 1 关于Android的非技术问题 1 1 1 为什么看好 Android 1 1 2 以前是否从事过Android的工作 做过哪些工作 1 1 3 你做的最复杂的界面是什么 1 1 [更多]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值