Android学习10Android上的数据存储02
来源:互联网 发布:java字符串补零 编辑:程序博客网 时间:2024/05/01 10:33
接上篇。
5. Content Provider使用
Content Provider属于Android应用程序的组件之一,在之前的文章已经有过介绍。作为应用程序之间唯一的共享数据的途经,Content Provider主要的功能是存储并检索数据,以及向其他应用提供访问数据的接口。
Android系统为常见的系统数据类型(如音频,视频,图像,手机通讯录联系人信息等)内置了一系列的Content Provider ,这些都位于android.provider包下。持有特定的许可,可以在自己开发的应用程序访问这些Content Provider
让自己的数据和其他的应用程序共享的方式有两种:创建自己的Content Provider(即继承自ContentProvider类)或者是将自己的数据添加到已有的Content Provider 中去,后者需要保证现有的Content Provider和自己的数据类型相同并且具有该Content Provider的写入权限。对于ContentProvider ,最终要的就是数据模型(data model)和URI。
(1)数据模型(data model)
Content Provider 将其存储的数据以数据表的形式提供给访问者,在数据表中每一行为一条记录,每一列具有特定类型和意义的数据。每一条数据记录都包括一个“——ID”数值字段,该字段唯一标识一条数据。
(2)URI
URI,每一个Content Provider都对外提供一个能够唯一标识自己数据集(data set)的公开URI,如果一个Content Provider管理多个数据集,其将会为每个数据集分配一个独立的URI。所有的Content Provider的URI都以“content://”开头,期中“content://”是用来标识数据是由Content Provider管理的scheme。
几乎所有的Content provider的操作中都会用到URI,因此一般来讲,如果自己开发Content Provider,最好将URI定义为常量,这样在简化开发的同时也提高了代码的可维护性。
首先介绍如何访问Content Provider中的数据,访问Content Provider中的数据主要通过ContentResolver类提供了成员方法可以用来对Content Provider中的数据进行查询,插入,修改和删除等操作。以查询为例,查询一个Content Provider需要掌握如下的信息:
唯一标识Content Provider;需要访问的数据字段名称;该数据字段的数据类型(如果需要访问特定的某条数据记录,只需该记录的ID即可)
查询Content Provider的方法有两个:ContentResolver的query()和Activity对象的managedQuery(),二者接收的参数相同,返回的都是Cursor对象,唯一的不同是使用managedQuery方法可以让Activity来管理Cursor的生命周期。
被管理的Cursor会在Activity进入暂停状态的时候调用自己的deactivate方法自行卸载,而在Activity回到运行态时会调用自己的query方法重新查询生成的Cursor对象。如果一个未被管理的Cursor对象想要被Activity管理,可以调用Activity的startManagingCursor方法来实现。
下面通过一个例子来说明访问Content Provider的方式:
首先在手机模拟器上运行“联系人”程序,添加两个联系人。
修改布局文件main.xml,改后代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/textView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
Activity类代码如下:
package karant.zhan;
import android.R.integer;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Contacts.People;
import android.widget.TextView;
public class ContentProviderTest extends Activity {
String [] columns = { //查询Content Provider时希望返回
People._ID,
People.NAME,
};
Uri contactUri = People.CONTENT_FILTER_URI; //访问Content Provider需要Uri
TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textView = (TextView)findViewById(R.id.textView);
String result = getQueryData(); //调用方法访问Content Provider
textView.setText("ID/t名字/n" + result); //将查询到的信息显示到TextView中
}
private String getQueryData() {
String result = "";
ContentResolver resolver = getContentResolver(); //获取ContentResolver对象
Cursor cursor = resolver.query(contactUri, columns, null, null, null);//调用方法查询Content Provider
int idIndex = cursor.getColumnIndex(People._ID); //获得额_ID字段的列索引
int nameIndex = cursor.getColumnIndex(People.NAME); //获得NAME字段的列索引
for(cursor.moveToFirst(); (!cursor.isAfterLast()); cursor.moveToNext()){ //遍历Cursor,提取数据
result = result + cursor.getString(idIndex) + "/t";
result = result +cursor.getString(nameIndex) + "/t/n";
}
cursor.close(); //关闭Cursor对象
return result;
}
}
最后还要修改AndoridMainfest.xml代码,只需要加入下面一行代码
<uses-permission android:name="android.permission.READ_CONTACTS" />
如果需要创建一个ContentProvider,则需要进行的工作主要分为下面三步:
(1)建立数据的存储系统
数据的存储系统可以由开发人员任意决定,一般来讲,大多数的Content Provider都通过Android的文件存储系统或SQLite数据库创建自己的数据库存储系统
(2)扩展ContentProvider类。
开发一个继承自ContentProvider类的子类代码来扩展ContentProvider类,在这个步骤主要工作是将要共享的数据包装并以ContentResolver和Cursor对象能够访问到的形式对外展示。具体来说需要实现ContentProvider类中的6个方法。
Cursor query(Uri uri,String[] projection, String selection, String [] selectionArgs,String sortOrder):将查询的数据以Cursor对象形式返回。
Uri insert(Uri uri,ContentValues values):向Content Provider 中插入新数据记录,ContentValues为数据记录的列名和列值的映射。
int update(Uri uri,ContentValues values,String selection, String[] selectionArgs): 更新Content Provider中已存在的数据记录。
int delete(Uri uri,String selection,String[] selectionArgs):从Content Provider中删除数据记录
String getType(Uri uri):返回Content Provider中数据的(MIME)类型。
boolean onCreate():当Content Provider启动被调用
以上方法会在ContentProvider对象中被调用,所以很好地实现这些抽象方法会为ContentResolver提供一个完善的外部接口,除了实现抽象方法外,还可以做一些提高可用性的工作。
定义一个URI类型的静态常量,命名为CONTENT_URI。 必须为改常量对象定义一个唯一的URI字符串,一般的做法是将ContentProvider子类的全程类名作为URI字符串,如“content://karant.zhan.Provider”
定义每个字段的列名,如果采用的数据存储系统为SQLite数据库,数据表列名可以采用数据库中表的列名。不管数据表中有没有其他的唯一标识一条记录的字段,都应该定义一个“_id”字段来唯一标识一条记录。一般将这些列名字符串定义为静态常量,如“_id”字段名定义为一个名为“_ID”值为“_id”的 静态字符串对象
(3)在应用程序的AndroidMainfest.xml文件声明Content Provider组件
创建好一个Content Provider必须要在应用程序的AndroidMainfest.xml中进行声明,否则该应用程序Content Provider对于Android系统将是不可见的。声明一个Content Provider组件的方法在之前文章有所介绍,如果有一个名为MyProvider的类扩展了ContentProvider类,声明该组件的代码如下:
<provider name = "karant.zhan.MyProvider"
authorities = "karant.zhan.myprovider"
.... />
</provider>
其中name属性为ContentProvider子类的全称类名,authorities属性标识了一个ContentProvider。
6. Preferences的使用
Preferences是一种应用程序内部轻量级的数据存储方案。Preferences主要用于存储和查询简单数据类型的数据,这些简单的数据类型包括boolean,int , float,long 以及String等,存储方式为以键值对的心事存放在应用程序的私有文件夹下。
Preferences一般用来存储应用程序的设置信息,如应用程序的色彩方案,文字文体等。在应用程序中获取Preferences的方式有一下两种:
(1)调用Context对象的getSharedPreferences方法获得SharedPreferences对象,需要传入SharedPreferences的名称和打开模式,名称为Preferences文件的名称,如果不存在则创建一个以传入名称为名的新Preferences文件:打开模式为PRIVATE,MODEL_WORLD,READABLE和MODE_WORLD_WRITEABLE其中之一。
(2)调用Activity对象的getPreferences方法获得SharedPreferences对象。需要传入打开模式,打开模式为PRIVATE,MODEL_WORLD,READABLE和MODE_WORLD_WRITEABLE其中之一。
两种获得SharedPreferences对象的最大不同就是通过Contxt对象的getSharedPreferences方法获得的对象可以被同一个应用程序下其他组件共享,而使用Activity对象的getPreferences方法获得对象只能被调用该方法所在的Activity使用。
SharedPreferences对象提供了一系列的get方法用于接收键返回对应的值,如果需要对Preferences文件中存储的键值进行修改,首先要调用SharedPreferences的edit方法获得一个Editor对象,该对象可以用来修改Preferences文件中存储的内容。
下面是一个Preferences的例子:
需要一个控件在布局文件中添加,修改后布局文件main.xml如下:
package karant.zhan;
import android.app.Activity;
import android.os.Bundle;
public class PreferencesTest extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Activity类代码如下:
package karant.zhan;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.EditText;
public class PreferencesTest extends Activity {
EditText editText; //EditText对象引用
SharedPreferences sharedPreferences; //SharedPreferences对象引用
public final String EDIT_TEXT_KEY = "EDIT_TEXT"; //定义Preferences文件中的键
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
editText = (EditText)findViewById(R.id.editText);
sharedPreferences = getPreferences(MODE_PRIVATE);
String result = sharedPreferences.getString(EDIT_TEXT_KEY, null);
if(result != null){
editText.setText(result);
}
}
@Override
protected void onDestroy() {
SharedPreferences.Editor editor = sharedPreferences.edit(); //获得ShredPreferences的Editor对象
editor.putString(EDIT_TEXT_KEY, String.valueOf(editText.getText()));//修改数据
editor.commit(); //不许调用该方法提交修改
super.onDestroy();
}
}
- Android学习10Android上的数据存储02
- Android学习9Android上的数据存储01
- android 学习 数据存储
- android数据存储的再学习
- Android的数据存储
- Android的数据存储
- android数据的存储
- Android 数据的存储
- Android的数据存储
- Android的数据存储
- Android 数据的存储
- Android 游戏中数据的存储(上)
- android数据存储学习记录
- android数据存储学习记录
- Android数据存储学习笔记
- Android学习之数据存储
- Android学习17--Android的数据存储和IO
- (疯狂的Android讲义 学习笔记)android数据存储
- day3-笔记
- 好烦啊
- java的锁的机制
- day4-笔记
- day5-笔记
- Android学习10Android上的数据存储02
- VB WINSOCK state常数
- java中文转拼音
- 转:scanf(), getchar(), 以及gets()函数注意点
- fatal error C1083: Cannot open precompiled header file: 'Debug/xxoo.pch': No such file or directory
- C#单进程解决方案
- TortoiseHg一款团队开发工具
- 转:scanf(), getchar(), 以及gets()函数注意点
- 实现简单Spring框架核心-------!!