第六章 android数据存储
DESCRIPTION
第六章 Android数据存储. 本章主要内容. Android 数据基本存储方式. SharedPreferences. Android 中的 SharedPreferences 是用来存储简单数据的一个工具类 ,它 通过用键值对的方式把简单的数据存储在应用程序的私有目录( data/data/< packagename >/ shared_prefs / )下指定的 xml 文件中 。 SharedPreferences 提供了一种轻量级的数据存储方式,通过 edit() 方法来修改存储内容,通过 commit() 方法提交修改后的内容。. - PowerPoint PPT PresentationTRANSCRIPT
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) :删除回调函数。
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 示例—— 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 关键代码 --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); }}