第六章 Android数据存储

36
第第第 Android 第第第第

description

第六章 Android数据存储. 本章主要内容. Android 数据基本存储方式. SharedPreferences. Android 中的 SharedPreferences 是用来存储简单数据的一个工具类 ,它 通过用键值对的方式把简单的数据存储在应用程序的私有目录( data/data/< packagename >/ shared_prefs / )下指定的 xml 文件中 。 SharedPreferences 提供了一种轻量级的数据存储方式,通过 edit() 方法来修改存储内容,通过 commit() 方法提交修改后的内容。. - PowerPoint PPT Presentation

Transcript of 第六章 Android数据存储

第六章 Android 数据存储

本章主要内容

Android 数据基本存储方式

Android 数据库编程——SQLite

Android 数据基本存储方式

SharedPreferences

Android 中的 SharedPreferences 是用来存储简单数据的一个工具类,它通过用键值对的方式把简单的数据存储在应用程序的私有目录( data/data/<packagename>/

shared_prefs/ )下指定的 xml 文件中。 SharedPreferences 提供了一种轻量级的数据存储方式,通过 edit() 方法来修改存储内容,通过 commit() 方法提交修改后的内容。

Android 数据基本存储方式

SharedPreferences 的重要方法

contains (String key) :检查是否已存在 key 这个关键字。

edit() :为 preferences 创建编辑器 Editor ,通过 Editor 可以修改 preferences 里面的数据,通过执行 commit() 方法提交修改。

getAll() :返回 preferences 所有的数据( Map )。

getBoolean(String key, boolean defValue) :获取 Boolean

型数据

getFloat(String key, float defValue) :获取 Float 型数据

getInt(String key, int defValue) :获取 Int 型数据

getLong(String key, long defValue) :获取 Long 型数据

Android 数据基本存储方式

SharedPreferences 的重要方法

getString(String key, String defValue) :获取 String 型数据

registerOnSharedPreferenceChangeListener(SharedP

references.OnSharedPreferenceChangeListener

listener) :注册一个当 preference 被改变时调用的回调函数。

unregisterOnSharedPreferenceChangeListener(Share

dPreferences.OnSharedPreferenceChangeListener

listener) :删除回调函数。

Android 数据基本存储方式

SharedPreferences 的示例

初始状态 保存后状态

save.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { SharedPreferences settings = getSharedPreferences(SETTING_INFOS,0);// 获取SharedPreferences 对象 // 关键代码:保存用户名、密码及性别 settings.edit().putString(NAME,username.getText().toString()).putString(PASSWORD,passwd.getText().toString()).putInt(SEX, sex.getSelectedItemPosition()).commit(); }});

Android 数据基本存储方式

SharedPreferences 的关键代码

Android 数据基本存储方式

SharedPreferences 的保存数据的原理

单击保存按钮时,会首先通过 getSharedPreferences()

方法得到 settings ,然后调用 edit() 方法得到编辑器Editor ,使用 Editor 的 putString 和 putInt 将编辑框及下拉列表的值进行修改,最后使用 commit() 方法将数据提交保存。更重要的是 SharedPreferences 只能由所属 package 的应用程序使用,而不能被其他应用程序使用。

Android 数据基本存储方式

Files

在大量数据需要存储时,可以借助于文件存储的功能。借助于 JAVA 文件 I/O 类,使用 FileInputStream 和FileOutputStream 类来读取和写入文件,典型代码:

String FILE_NAME = "filename.txt";// 确定要操作文件的文件名FileOutputStream fos = openFileOutput(FILE_NAME,Context.MODE_PRIVATE);// 创建输出流FileInputStream fis = openFileInput(FILE_NAME);// 创建输

入流

Android 数据基本存储方式

Files

1. 若创建 FileOutputStream 时指定的文件不存在,系统会自动创建这个文件。

2. 默认的写入操作会覆盖源文件的内容,如果想要把新写入的内容附加在原文件的内容之后,可以指定模式为Context.MODE_APPEND 。

3. 默认地,使用 openFileOutput 方法打开的文件只能被其调用的应用程序使用,其他应用程序将无法读取这个文件。

4. 如果需要在不同的应用程序中共享数据,可以使用ContentProvider (将在后面提到)。

使用文件输入输出流的注意事项:

Android 数据基本存储方式

Files 示例

初始状态 新建文件

Android 数据基本存储方式

Files 示例

保存成功 文件列表

Android 数据基本存储方式

Files 示例—— Layout 布局

LinearLayout(垂直方向)

TextView

EditText

LinearLayout(水平方向)

TextView

ListView

Button

Button

Button

Android 数据基本存储方式

Files 示例——关键代码如下:

public class FileIODemoActivity extends ListActivity {TextView tw = null;EditText et = null;Button save;

private File mTextFilePath = null;// 保存文件路径 private File mTextFile = null;// 新建文件名称 private String strTextFilePrefix = "FileIOTest_";// 保存文件前缀 private List<String> mTextFileList = new ArrayList<String>();// 以保存文件列表

/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); tw = (TextView)findViewById(R.id.tw); et = (EditText)findViewById(R.id.et); mTextFilePath = new File("/data/data/com.android.example.fileiodemo/"); if(!mTextFilePath.exists()){ mTextFilePath.mkdirs(); } save = (Button)findViewById(R.id.save); save.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

try {savefile();showDialog(R.id.dialog_save_success);if (mTextFile != null){ mTextFileList.add(mTextFile.getName());

ArrayAdapter<String> musicList = new ArrayAdapter<String>(FileIODemoActivity.this, R.layout.list, mTextFileList);

setListAdapter(musicList);}} catch (IOException e) { e.printStackTrace(); } } });

Android 数据基本存储方式

Files 示例——关键代码如下:

Button create_new_file = (Button)findViewById(R.id.new_file); create_new_file.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

try {mTextFile = File.createTempFile(strTextFilePrefix, ".txt", mTextFilePath);Log.v("duanhong", " 创建文件 " + mTextFile.getName());showDialog(R.id.dialog_create_success);readfile(mTextFile);save.setClickable(true);save.setEnabled(true);} catch (IOException e) {e.printStackTrace();} } });

Button helpInfo = (Button)findViewById(R.id.help); helpInfo.setOnClickListener(new OnClickListener() {

@Overridepublic void onClick(View v) {

try {helpdoc();

} catch (IOException e) {e.printStackTrace();

} } }); textFileList(); try {

helpdoc();} catch (IOException e) {

e.printStackTrace();} }

Android 数据基本存储方式

Files 示例——关键代码如下:

protected void savefile() throws IOException {

FileOutputStream fos = new FileOutputStream(mTextFile); fos.write(et.getText().toString().getBytes()); Log.v("duanhong", " 写入文件 "); fos.flush(); fos.close();

}

private void helpdoc() throws IOException{ save.setClickable(false); save.setEnabled(false); tw.setText(" 帮助文档,不可编辑 "); String myString = null; InputStream is= getApplicationContext().getContentResolver() .openInputStream(Uri.parse("android.resource://" + "com.android.example.fileiodemo/" + R.raw.help)); BufferedInputStream bis = new BufferedInputStream(is); ByteArrayBuffer baf = new ByteArrayBuffer(8192); int current = 0; while((current = bis.read()) != -1) { baf.append((byte)current); } myString = new String(baf.toByteArray(),"GBK"); et.setText(myString); }

Savefile() 方法用于保存文件

Helpdoc() 方法显示程序的帮助文档

Android 数据基本存储方式

Files 示例——关键代码如下:

private void readfile(File file) throws IOException{ mTextFile = file; tw.setText(" 正在编辑文件 " + mTextFile.getName()); if(!mTextFile.exists()){ Log.v("duanhong", " 创建文件 "); if(!mTextFile.createNewFile()){ Log.v("duanhong"," 创建文件失败 "); return; } } String myString = null; InputStream is = new FileInputStream(mTextFile);// 创建写入流 BufferedInputStream bis = new BufferedInputStream(is); ByteArrayBuffer baf = new ByteArrayBuffer(8192); int current = 0; while((current = bis.read()) != -1) { baf.append((byte)current); } myString = new String(baf.toByteArray());// 这个出现乱码,要在 txt 文件保存时选中 utf-8 et.setText(myString); }

@Override /* 点击列表中某项时,打开被点击的文件 */protected void onListItemClick(ListView l, View v, int position, long id){ /* 得到被点击的文件 */

mTextFile = new File(mTextFilePath.getAbsolutePath() + File.separator + mTextFileList.get(position));/* 播放 */try { readfile(mTextFile);} catch (IOException e) {

// TODO Auto-generated catch blocke.printStackTrace();}

save.setClickable(true); save.setEnabled(true); }

readfile() 方法用于打开文件

Android 数据基本存储方式

ContentProvider

在 Android 中,使用 URI 来定位文件和数据资源。相比常见的与之容易混淆的 URL ( Uniform Resource Locator ,统一资源定位器), URL 是用于标识资源的物理位置,相当于文件的路径;而 URI 则是标识资源的逻辑位置,并不提供资源的具体位置。 一旦文件的存储路径改变, URL 也必须随之改动;而对于 URI ,可以用诸如 content://contract/people 这样的逻辑地址来标识。

Android 数据基本存储方式

ContentProvider

ContentProvider 是应用程序私有数据对外的接口。Activity 类中有一个继承自 ContentWapper 的

getContentResolver() 无参数方法,该方法返回一个ContentResolver 对象,通过调用其query 、 insert 、 update 、 delete 方法访问数据。这几个方法的第一个参数均为 URI ,用来标识需要访问的资源或数据库。

Android 数据基本存储方式

ContentProvider 格式

ContentProvider URI 固定的形式如下,以联系人应用程序为例:

content : // contract / people / 001

A B C D

A :类似于 URL 中的 http:// 、 ftp:// 等等;B :资源的唯一标识符,可以理解为数据库名;C :具体的资源类型,可以理解为数据库表名。D : ID 号,用于指定一条数据,可以理解为数据库中的某一行的 id 。

Android 数据基本存储方式

ContentProvider

ContentResolver 是用于访问通过 ContentProvider 获取的其他应用程序所共享的数据的类。

ContentProvider 负责 (1) 组织应用程序的数据; (2) 向其他应用程序提供数据。ContentResolver 负责 (1) 获取 ContentProvider 提供的数据; (2) 修改 / 添加 / 删除更新数据等。

Android 数据基本存储方式

ContentProvider

ContentProvider 向外界提供数据操作的接口:query(Uri, String[], String, String[], String)

insert(Uri, ContentValues)

update(Uri, ContentValues, String, String[])

delete(Uri, String, String[])思考两个

问题

1.ContentProvider 是什么时候创建的,是谁创建的?

2.若多个程序同时通过 ContentResolver 访问一个 ContentProvider ,会不会导致类似数据库的“脏数据”?

Android 数据库编程——SQLite

简介

SQLite 是一款开源的轻量级嵌入式关系型数据库。它在2000年由 D. Richard Hipp发布,支持Java 、 Net 、 PHP 、 Ruby 、 Python 、 Perl 、 C 等几乎所有的现代编程语言,并且支持Windows 、 Linux 、 Unix 、 Mac OS 、 Android 、 iOS等几乎所有的主流操作系统平台。 SQLite 被广泛的应用在苹果、 Adobe 、 Google 的各项产品中。在 Android 中也内置了完整支持的 SQLite 数据库。

Android 数据库编程——SQLite

SQLite特性

遵守 ACID ; 零配置——无需安装和管理配置; 储存在单一磁盘文件中的一个完整的数据库; 数据库文件可以在不同字节顺序的机器间自由的共享; 支持数据库大小至 2TB ; 足够小,约 3万行 C 代码, 250K ; 比一些流行的数据库在大部分普通数据库操作要快; 简单的 API ; 包含 TCL绑定,同时通过 Wrapper支持其他语言的绑定; 良好注释的源代码,并且有着 90% 以上的测试覆盖率; 独立:没有额外依赖; Source完全的 Open ,可以用于任何用途,包括出售它; 支持多种 开发语言: C 、 PHP 、 Perl 、 Java 、 ASP.NET 和

Python 。

SQLite 是一款开源的轻量级嵌入式关系型数据库。 SQLite 数据库具有如下的一系列特性:

Android 数据库编程——SQLite

SQLite 示例

Android 数据库编程——SQLite

SQLite 示例

Android 数据库编程——SQLite

SQLite 关键代码 --DBHelper

创建数据库public class DBHelper extends SQLiteOpenHelper { Context context;// 应用环境上下文 private static SQLiteDatabase db;// 该辅助类维护的数据库对象 public String table_name = "files";// 数据库表名 private static final String TAG = "duanhong";// 调试标签 private String name;// 数据库名 public DBHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); this.context = context; this.name = name; db = context.openOrCreateDatabase(name, Context.MODE_PRIVATE,null); drop_table();//清除数据库,便于测试 CreateTable();//辅助类建立时运行该方法建立数据库 } …}

Android 数据库编程——SQLite

SQLite 关键代码 --DBHelper

创建表private void CreateTable() { try {// 使用 execSQL 方法执行 sql语句完成数据库表创建 db.execSQL("CREATE TABLE IF NOT EXISTS " + table_name + "(" + "_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + "fileName VARCHAR, description VARCHAR" + ");"); Log.v(TAG, "Create Table files ok"); } catch (Exception e) { Log.v(TAG, e.toString()); } }

Android 数据库编程——SQLite

SQLite 关键代码 --DBHelper

初始化表

// 初始化表,使用 SQLiteDatabase 提供的 insert 方法插入一行数据public void initDatabase(){ ContentValues cv = new ContentValues();// 数据集,表示一行数据 cv.put("fileName", "Test"); cv.put("description", " 初始化测试项 "); db.insert(table_name, "", cv);}

Android 数据库编程——SQLite

SQLite 关键代码 --DBHelper

插入条目public boolean insert(String filename, String description){ String sql=""; try{ // 打开数据库供后续操作使用 db = context.openOrCreateDatabase(name, Context.MODE_PRIVATE,null); sql="insert into files values(null,'"+ filename + "','" + description +"')"; db.execSQL(sql); Log.v(TAG,"insert Table files ok"); return true; }catch(Exception e){ Log.v(TAG,"insert Table files err ,sql: "+sql); return false; } }

Android 数据库编程——SQLite

SQLite 关键代码 --DBHelper

删除条目public boolean delete(int fileid){String sql=""; try{ db = context.openOrCreateDatabase(name, Context.MODE_PRIVATE,null); sql="delete from files where _id=" + fileid; db.execSQL(sql); Log.v(TAG,"delete item ok"); return true; }catch(Exception e){ Log.v(TAG,"delete item err ,sql: "+sql); return false; }}

Android 数据库编程——SQLite

SQLite 关键代码 --DBHelper

修改条目public boolean update(int fileid, String filename, String description){ String sql=""; try{ db = context.openOrCreateDatabase(name, Context.MODE_PRIVATE, null); sql="update files set fileName='" + filename + "',description='" + description +"' where _id=" + fileid; db.execSQL(sql); Log.v(TAG,"update Table files ok"); return true; }catch(Exception e){ Log.v(TAG,"update Table files err ,sql: "+sql); return false; }}

Android 数据库编程——SQLite

SQLite 关键代码 --DBHelper

查询条目 public Cursor select(int fileid){ String sql="_id=" + fileid; db = context.openOrCreateDatabase(name, Context.MODE_PRIVATE,null); Cursor cur=db.query(table_name, new String[]{"_id","fileName","description"}, sql, null, null, null, null); return cur; }

public Cursor loadAll(){// 返回可得到数据库所有表项的 Cursor db = context.openOrCreateDatabase(name, Context.MODE_PRIVATE,null); Cursor cur=db.query(table_name, new String[]{"_id","fileName","description"}, null, null, null, null, null); return cur; }

读取所有条目

Android 数据库编程——SQLite

SQLite 关键代码 --DBHelper

删除表public void drop_table(){ String sql=""; try{ db = context.openOrCreateDatabase(name, Context.MODE_PRIVATE, null); sql="drop table " + table_name; db.execSQL(sql); Log.v(TAG,"drop Table files ok"); }catch(Exception e){ Log.v(TAG,"drop Table files err ,sql: "+sql); }}

本章小结

本章介绍了如何在 Android 中使用 SQLite 数据库。众所周知,数据库跟程序的联系十分紧密,可以说很多程序都离不开数据库,本章做了一个简单的介绍,请读者在课后多加联系,熟练掌握。

THE END