数据持久化
来源:互联网 发布:柏林战役 知乎 编辑:程序博客网 时间:2024/06/06 02:40
在Android中,实现数据持久化主要有四种方式:Preferences,文件I/O,SQLite数据库,ContentProvider组件。
这里面讲的也很好:http://www.cnblogs.com/weixing/p/3243115.html
Preferences
Preferences是一种轻量级的数据存储机制,他将一些简单的数据类型的数据,包括boolean类型,int类型,float类型,long类型以及String类型的数据,以键值对的形式存储在应用程序的私有Preferences目录(/data/data/<包名>/shared_prefs/)中,这种Preferences机制广泛应用于存储应用程序中的配置信息。
SharedPreferences sharedPreferences = getSharedPreferences("ljq", Context.MODE_PRIVATE);//如果ljq不存在,则会自动新建
Editor editor = sharedPreferences.edit();//获取编辑器,然后就可以编辑它
editor.putString("name", "cjw");
editor.putInt("age", 4);
editor.commit();//提交修改
写入数据:
sPrefs = PreferenceManager.getDefaultSharedPreferences(context);
sPrefs.edit().putInt(SCREEN_COUNT, count).commit();
查看Preferences中的数据的方法有两种:
第一种是使用adb命令查看;
第二是使用DDMS——>FileExplorer在目录/data/data/<包名>/shared_prefs/中Preferences导出来查看。
如何访问其他应用中的Preference?
public void testAccessPreference2() throws Exception{
Context context = this.getContext().createPackageContext("com.ljq.activity",
Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences sharedPreferences = context.getSharedPreferences("ljq123",
Context.MODE_WORLD_READABLE+Context.MODE_WORLD_WRITEABLE);
String name = sharedPreferences.getString("name", "");
int age = sharedPreferences.getInt("age", 1);
Log.i(TAG, name + " : " +age);
}
2)文件I/O
1.使用内部存储器
创建:
- Call openFileOutput()
with the name of the file and the operating mode. This returns aFileOutputStream.
- Write to the file with write().
- Close the stream with close().
String FILENAME = "hello_file";
String string = "hello world!";
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
- Call openFileInput()
- and pass it the name of the file to read. This returns a FileInputStream.
- Read bytes from the file with read().
- Then close the stream with close().
res/raw/
directory. You can open it with openRawResource()
, passing the R.raw.<filename>
resource ID. This method returns an InputStream that you can use to read the file (but you cannot write to the original file).比如QQ的提示音其他有用的方法
- 获取绝对路径到你的内部文件保存在文件系统中的目录。
- 创建(或打开一个现有的),你的内部存储空间中的目录。
- 删除保存在内部存储的文件。
- fileList()
- 返回当前保存您的应用程序文件的数组
为了读取或写入外部存储文件,您的应用程序必须获得 READ_EXTERNAL_STORAGE 或WRITE_EXTERNAL_STORAGE系统权限。例如:
<manifest ... >
<uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
如果你需要同时读取和写入文件,那么你需要请求只有 WRITE_EXTERNAL_STORAGE权限,因为它隐含地要求读访问也是如此。
4.4之后私有的读取就不需要申明
2.Before you do any work with the external storage, you should always call getExternalStorageState() to check whether the media is available./* Checks if external storage is available for read and write 可读可写的检查*/
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();// Environment提供环境变量的访问
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/* Checks if external storage is available to at least read只读的检查 */
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
public File getAlbumStorageDir(String albumName) {
// Get the directory for the user's public pictures directory.
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), albumName);
if (!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
return file;
}
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
...
</manifest>
getExternalFilesDirs()来获取一个文件数组,第一个基本的外部存储SD
调用
getExternalCacheDir()方法,类似ContextCompat.getExternalFilesDirs()
,上面提到的,你也可以通过调用访问的辅助外部存储(如果有的话)的缓存目录 ContextCompat.getExternalCacheDirs() 。Android平台主要通过java.io.FileInputStream和java.io.FileOutputStream这两个类来实现对文件的读写,java.io.File类则用来构造一个具体指向某个文件或者文件夹的对象。
需要注意的是:每个应用程序所在的包都会有一个私有的存储数据的目录,只有属于这个包中的应用程序才有写入的权限,每个包中应用程序的私有数据目录位于 Android系统中的绝对路径/data/data/<package>/目录中,除了私有目录,应用程序还拥有/sdcard目录即 Android设备上的SD卡的写入权限。文件系统中其他的系统目录,第三方应用程序都是不可写的。
在我们RUI中,下载推荐应用时,就是在SD卡中建立一个目录,将下载的apk放入该目录中,具体的实现可以查看com.rui.mid.launcher.service.download中的FileUtil.java文件。在该文件中有一个changeMode方法改变文件的权限(可读,可写,可执行),就是为了能让系统调用该apk,实现应用的安装。
3)SQLite数据库
当应用程序需要处理的数据量比较大时,为了更加合理地存储、管理、查询数据,我们往往使用关系数据库来存储数据。Android平台为开发者提供了SQLite数据库相关的API来实现对数据库操作的支持,开发人员可以很方便的使用这些API来对SQLite数据库进行创建、修改及查询等操作。Android系统的很多用户数据,如联系人信息,通话记录,短信息等,都是存储在SQLite数据库当中的,所
以利用操作SQLite数据库的API可以同样方便的访问和修改这些数据。
在实际的应用程序编写中,为了更好的对SQlite数据的创建,打开,更改进行管理,往往会编写一个SQLiteOpenHelper的数据库辅助类来帮助我们创建和打开数据库。可以查考博客http://blog.csdn.net/rhljiayou/article/details/7085347
源码:
package com.example.usingpreference;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import android.os.Bundle;import android.app.Activity;import android.content.Context;import android.content.SharedPreferences;import android.content.SharedPreferences.Editor;import android.view.Menu;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;public class MainActivity extends Activity {private EditText parem1;private EditText parem2;private Button save;private Button show;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);parem1 = (EditText) this.findViewById(R.id.editText1);parem2 = (EditText) this.findViewById(R.id.editText2);save = (Button) this.findViewById(R.id.button1);show = (Button) this.findViewById(R.id.button2);// 进入应用使用直接显示上次保存的输入SharedPreferences sharedPreferences = getSharedPreferences("chenjianwu", MODE_PRIVATE);parem1.setText(sharedPreferences.getString("name", ""));parem2.setText(Integer.toString(sharedPreferences.getInt("age", 1)));// 取缓存数据(/data/data/cache)追加显示String appendCache = null;try {appendCache = getCache("cjw");} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}parem1.append("+缓存追加:" + appendCache);// 读取内部存储器数据,追加显示String appendInternal = null;try {appendInternal = getInternal("hello_file");} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}parem1.append("+读取内部存储器追加:"+appendInternal);}/** * 按钮监听事件,保存数据和显示数据 * @param view * @throws IOException */public void listener(View view) throws IOException {Button button = (Button) view;String name = parem1.getText().toString().trim();int age = Integer.parseInt(parem2.getText().toString().trim());SharedPreferences preferences = getSharedPreferences("chenjianwu",MODE_PRIVATE);switch (button.getId()) {case R.id.button1:Editor editor = preferences.edit();// 声明编辑器,编辑内容后commit()来提交编辑结果editor.putString("name", name);editor.putInt("age", age);editor.commit();// 使用内部存储器保存文件String FILENAME = "hello_file";String string = "hello world 你好!";FileOutputStream fos = openFileOutput(FILENAME,Context.MODE_PRIVATE);fos.write(string.getBytes());fos.close();// 使用缓存文件保存数据File catchFile = new File(getCacheDir(), "cjw");// getCacheDir()返回cache的绝对路劲FileOutputStream catchoutput = new FileOutputStream(catchFile);catchoutput.write(string.getBytes());break;case R.id.button2:parem1.setText(preferences.getString("name", ""));parem2.setText(Integer.toString(preferences.getInt("age", 1)));default:break;}}/** * 读取缓存文件内容(/data/data/cache) * * @param filename * 文件名 * @return 返回Sting类型 * @throws IOException */public String getCache(String filename) throws IOException {File f = new File(getCacheDir(), filename);FileInputStream fis = new FileInputStream(f);ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] data = new byte[1024];int len = -1;while ((len = fis.read(data)) != -1) {baos.write(data, 0, len);}return new String(baos.toByteArray());}/** * 获取内部存储器文件内容(/data/data/files) * * @param filename * @return * @throws IOException */public String getInternal(String filename) throws IOException {FileInputStream fis = openFileInput(filename);//调用openFileInput()来获取内部存储器输入流ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] data = new byte[1024];int len = -1;while ((len = fis.read(data)) != -1) {baos.write(data, 0, len);}return new String(baos.toByteArray());}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}}
布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="参数1:" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView1" android:layout_below="@+id/textView1" android:layout_marginTop="64dp" android:text="参数2:" /> <EditText android:id="@+id/editText1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignTop="@+id/textView2" android:layout_toRightOf="@+id/textView2" android:ems="10" > <requestFocus /> </EditText> <EditText android:id="@+id/editText2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignTop="@+id/textView1" android:layout_toRightOf="@+id/textView1" android:ems="10" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView2" android:layout_below="@+id/editText1" android:layout_marginTop="129dp" android:text="保存" android:onClick="listener"/> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/button1" android:layout_alignBottom="@+id/button1" android:layout_alignRight="@+id/editText1" android:text="显示" android:onClick="listener" /></RelativeLayout>
- 什么是数据持久化?
- 数据持久化
- 数据持久化
- 什么是数据持久化
- 数据持久化
- 数据持久化
- redis数据持久化
- Android 数据持久化
- 数据持久化
- 数据持久化
- JForum数据持久化
- IOS 数据持久化
- 浅谈数据持久化
- 浅谈数据持久化
- Android 数据持久化
- iOS 数据持久化
- 数据持久化
- ios数据持久化
- 详解YUV数据格式
- UItextview 怎么实现placeholder属性
- 几种正则的表达
- MySQL随笔
- 测试之路2——对比XML文件1
- 数据持久化
- Android屏幕备选资源
- orcale数据恢复
- ZOJ 3396 Conference Call 最短路
- 面试题之交通灯管理系统
- MM01 BDC录屏实例
- Android 进阶学习:Android自定义View的实现方法,带你一步步深入了解View(四)
- 嵌入tomcat7
- 使用Math.floor和Math.random取随机整数