360 likes | 497 Views
第六章 Android数据存储. 本章主要内容. Android 数据基本存储方式. SharedPreferences. Android 中的 SharedPreferences 是用来存储简单数据的一个工具类 ,它 通过用键值对的方式把简单的数据存储在应用程序的私有目录( data/data/< packagename >/ shared_prefs / )下指定的 xml 文件中 。 SharedPreferences 提供了一种轻量级的数据存储方式,通过 edit() 方法来修改存储内容,通过 commit() 方法提交修改后的内容。.
E N D
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, booleandefValue):获取Boolean型数据 • getFloat(String key, float defValue):获取Float型数据 • getInt(String key, intdefValue):获取Int型数据 • getLong(String key, long defValue):获取Long型数据
Android数据基本存储方式 SharedPreferences的重要方法 • getString(String key, String defValue):获取String型数据 • registerOnSharedPreferenceChangeListener(SharedPreferences.OnSharedPreferenceChangeListener listener):注册一个当preference被改变时调用的回调函数。 • unregisterOnSharedPreferenceChangeListener(SharedPreferences.OnSharedPreferenceChangeListener listener):删除回调函数。
Android数据基本存储方式 SharedPreferences的示例 初始状态 保存后状态
Android数据基本存储方式 SharedPreferences的关键代码 save.setOnClickListener(newOnClickListener() { @Override publicvoidonClick(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的保存数据的原理 单击保存按钮时,会首先通过getSharedPreferences()方法得到settings,然后调用edit()方法得到编辑器Editor,使用Editor的putString和putInt将编辑框及下拉列表的值进行修改,最后使用commit()方法将数据提交保存。更重要的是SharedPreferences只能由所属package的应用程序使用,而不能被其他应用程序使用。
Android数据基本存储方式 Files 在大量数据需要存储时,可以借助于文件存储的功能。借助于JAVA文件I/O类,使用FileInputStream和FileOutputStream类来读取和写入文件,典型代码: String FILE_NAME = "filename.txt";//确定要操作文件的文件名 FileOutputStreamfos = openFileOutput(FILE_NAME,Context.MODE_PRIVATE);//创建输出流 FileInputStreamfis = openFileInput(FILE_NAME);//创建输入流
Android数据基本存储方式 Files 使用文件输入输出流的注意事项: 若创建FileOutputStream时指定的文件不存在,系统会自动创建这个文件。 默认的写入操作会覆盖源文件的内容,如果想要把新写入的内容附加在原文件的内容之后,可以指定模式为Context.MODE_APPEND。 默认地,使用openFileOutput方法打开的文件只能被其调用的应用程序使用,其他应用程序将无法读取这个文件。 如果需要在不同的应用程序中共享数据,可以使用ContentProvider(将在后面提到)。
Android数据基本存储方式 Files示例 初始状态 新建文件
Android数据基本存储方式 Files示例 保存成功 文件列表
Android数据基本存储方式 Files示例——Layout布局 TextView EditText Button LinearLayout(垂直方向) LinearLayout(水平方向) Button TextView Button ListView
public class FileIODemoActivity extends ListActivity { TextViewtw = 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() { @Override public 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示例——关键代码如下:
Android数据基本存储方式 Button create_new_file = (Button)findViewById(R.id.new_file); create_new_file.setOnClickListener(new OnClickListener() { @Override public 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() { @Override public void onClick(View v) { try { helpdoc(); } catch (IOException e) { e.printStackTrace(); }}}); textFileList(); try { helpdoc(); } catch (IOException e) { e.printStackTrace(); } } Files示例——关键代码如下:
Android数据基本存储方式 protected void savefile() throws IOException { FileOutputStreamfos = 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)); BufferedInputStreambis = new BufferedInputStream(is); ByteArrayBufferbaf = new ByteArrayBuffer(8192); int current = 0; while((current = bis.read()) != -1) { baf.append((byte)current); } myString = new String(baf.toByteArray(),"GBK"); et.setText(myString); } Files示例——关键代码如下: Savefile() 方法 用于保存文件 Helpdoc() 方法显示程序的帮助文档
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);//创建写入流 BufferedInputStreambis = new BufferedInputStream(is); ByteArrayBufferbaf = 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 block e.printStackTrace(); } save.setClickable(true); save.setEnabled(true);} Android数据基本存储方式 readfile() 方法 用于打开文件 Files示例——关键代码如下:
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,用来标识需要访问的资源或数据库。
content : // contract / people / 001 A B C D Android数据基本存储方式 ContentProvider格式 ContentProvider URI固定的形式如下,以联系人应用程序为例: 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特性 SQLite是一款开源的轻量级嵌入式关系型数据库。 SQLite数据库具有如下的一系列特性: • 遵守ACID; • 零配置——无需安装和管理配置; • 储存在单一磁盘文件中的一个完整的数据库; • 数据库文件可以在不同字节顺序的机器间自由的共享; • 支持数据库大小至2TB; • 足够小,约3万行C代码,250K; • 比一些流行的数据库在大部分普通数据库操作要快; • 简单的API; • 包含TCL绑定,同时通过Wrapper支持其他语言的绑定; • 良好注释的源代码,并且有着90%以上的测试覆盖率; • 独立:没有额外依赖; • Source完全的Open,可以用于任何用途,包括出售它; • 支持多种开发语言:C、PHP、Perl、Java、ASP.NET和Python。
Android数据库编程——SQLite SQLite示例
Android数据库编程——SQLite SQLite示例
Android数据库编程——SQLite SQLite关键代码--DBHelper 创建数据库 publicclassDBHelperextendsSQLiteOpenHelper { Context context;//应用环境上下文 privatestaticSQLiteDatabasedb;//该辅助类维护的数据库对象 public String table_name = "files";//数据库表名 privatestaticfinal String TAG = "duanhong";// 调试标签 private String name;//数据库名 publicDBHelper(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 创建表 privatevoidCreateTable() { 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方法插入一行数据 publicvoidinitDatabase(){ ContentValuescv = newContentValues();//数据集,表示一行数据 cv.put("fileName", "Test"); cv.put("description", "初始化测试项"); db.insert(table_name, "", cv); }
Android数据库编程——SQLite SQLite关键代码--DBHelper 插入条目 publicboolean 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"); returntrue; }catch(Exception e){ Log.v(TAG,"insert Table files err ,sql: "+sql); returnfalse; } }
Android数据库编程——SQLite SQLite关键代码--DBHelper 删除条目 publicboolean delete(intfileid){ 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"); returntrue; }catch(Exception e){ Log.v(TAG,"delete item err ,sql: "+sql); returnfalse; } }
Android数据库编程——SQLite SQLite关键代码--DBHelper 修改条目 publicboolean update(intfileid, 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"); returntrue; }catch(Exception e){ Log.v(TAG,"update Table files err ,sql: "+sql); returnfalse; } }
Android数据库编程——SQLite SQLite关键代码--DBHelper 查询条目 public Cursor select(intfileid){ 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 删除表 publicvoiddrop_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数据库。众所周知,数据库跟程序的联系十分紧密,可以说很多程序都离不开数据库,本章做了一个简单的介绍,请读者在课后多加联系,熟练掌握。