Android开发学习 -- Day13 数据存储方案 -- 持
任何应用说起来都是再跟数据打交道,聊微信、逛头条都是在享受不同的数据,如果没有数据,应用就会变成一个空壳子,对用户没有任何意义。在之前的学习中,不论是简易的聊天demo还是登陆功能,我们所有的数据都是存在内存当中的。当程序关闭或者内存被系统回收时,这些数据就会丢失掉。要想保留数据,就需要用到持久化技术。
一、持久化技术
数据持久化就是指将那些内存中的瞬时数据存储到设备中,保证及时在手机或者电脑关机的情况下,这些数据仍然不会丢失。在Android系统中,主要提供了3种方式用于简单的实现数据持久化功能,即文件存储、SharedPreferences存储以及数据库存储。
二、文件存储
文件存储是Android中一种最基本的数据存储方式,它不对存储的内容进行任何的格式化处理,所有的数据都是原封不动的保存到文件当中,因此它适合用于存储一些建安的文本数据或二进制数据。
1、将数据存储到文件
Context类中提供了一个openFileOutput()方法,可以用于将数据存储到制定的文件中。这个方法接收两个参数,第一个参数是文件名,第二参数是文件的操作模式。文件名中不可以包含路径,因为所有的文件默认都是存储到/data/data/packagename/files/目录下面。操作模式主要有两种模式可选,MODE_PRIVATE和MODE_APPEND。其中MODE_PRIVATE是默认操作模式,表示指定同样文件名的时候,所写入的数据将会覆盖原文件的内容;MODE_APPEND表示如果文件已存在,就往文件里追加内容。
openFileOutput()方法返回的是一个FileOutputStream对象,得到这个对象之后,就可以使用java流的方式将数据写入到文件中。
public class PersSaveFileActivity extends BaseActivity {
private EditText editText;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pers_save_file);
setTitle("将数据存储到文件中");
editText = findViewById(R.id.edit_content_save_file);
}
public void save(String string) {
if (TextUtils.isEmpty(string)) {
return;
}
FileOutputStream out = null;
BufferedWriter writer = null;
try {
// openFileOutput 文件名字 和 类型
out = openFileOutput("data", Context.MODE_PRIVATE);
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(string);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
protected void onStop() {
super.onStop();
String str = editText.getText().toString();
save(str);
}
}
在onCreate()方法中获取到EditText的实例,然后在onStop()中执行save()方法把输入的内容存储到本地文件中。save()方法中,首先通过openFileOutput()方法得到一个FileOutputStream对象,然后再借助它构造一个OutputStreamWriter对象,接着使用它构建一个BufferedWriter对象,这样就可以通过BufferedWriter将文本内容写进文件中了。
2、从文件中读取数据
类似将文件存储到文件,Context类还提供了一个openFileInput()方法,用于从文件中读取数据。它只接收一个参数,即要读取的文件的名字,然后系统会自动到/data/data/packagename/files/目录下去加载这个文件,并返回一个FileInputStream对象。通过它我们就可以使用java流将数据读出。
修改Activity,添加代码:
public class PersSaveFileActivity extends BaseActivity {
private EditText editText;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pers_save_file);
setTitle("将数据存储到文件中");
editText = findViewById(R.id.edit_content_save_file);
textView = findViewById(R.id.text_save_to_file);
String content = load();
if (!TextUtils.isEmpty(content)) {
textView.setText(content);
Toast.makeText(this, "从本地恢复的数据", Toast.LENGTH_SHORT).show();
}
}
public String load() {
FileInputStream in = null;
BufferedReader reader = null;
StringBuilder content = new StringBuilder();
try {
in = openFileInput("data");
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
content.append(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return content.toString();
}
...
}
首先我们在onCreate()方法中调用load()方法,如果读取的数据不为空,就将它展示在TextView中,并弹出Toast提示。再来看load()方法,首先通过openFileInput()获取到FileInputStream对象,接着通过FileInputStream构建一个InputStreamReader对象,再借助它构建一个BufferedReader对象,然后使用BufferedReader的readLine()方法,就能一行一行读出文件,并把数据存在一个StringBuilder对象中,最后将读取到的内容返回就可以了。
三、SharedPreferences存储
不同于文件存储,SharedPreferences是使用键值对的方式来存储数据的。
1、将数据存储到SharedPreferences中
要想使用SharedPreferences来存储数据,就得先得到SharedPreferences对象,Android提供了3种方法用于得到SharedPreferences对象。
□ Context类中的getSharedPreferences()方法
这个方法接收两个参数,第一个参数用于指定SharedPreferences文件名称,如果文件不存在则创建一个。SharedPreferences文件都是存放于/data/data/packagename/shared_prefs/目录下。第二个参数用于指定操作模式,目前只有MODE_PRIVATE一种可选,表示只有当前的应用能够对这个文件进行读写。
□ Activity类中的getPreferences()方法
和Context类中的getSharedPreferences()类似,只不过它只接收一个操作模式的参数,调用这个方法会自动将当前的Activity类名作为SharedPreferences文件名。
□ PreferenceManager类中的getDefaultSharedPreferences()方法
这是一个静态方法,他接收一个Context参数,并自动使用当前应用的包名作为SharedPreferences文件名。
得到SharedPreferences对象后,就可以向SharedPreferences文件中存储数据了,主要有3步:
1)调用SharedPreferences对象的edit()方法获取SharedPreferences.Editor对象
2)向SharedPreferences.Editor对象中添加数据
3)调用apply()方法将添加的数据提交
下面就快速的体验下SharedPreferences存储:
public class PreSharedPreferencesActivity extends BaseActivity {
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pre_shared_preferences);
setTitle("SharedPreferences");
btn = findViewById(R.id.btn_save_sharedprefs);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();
editor.putString("name", "John");
editor.putInt("age", 30);
editor.putBoolean("married", false);
editor.apply();
}
});
}
}
我们这里只添加了一个按钮,在点击事件中,首先通过getSharedPreferences()指定了存储的文件名,并得到了SharedPreferences.Editor对象,然后通过putString等方法添加不同类型的数据,最后调用apply()方法进行提交,从而完成数据的存储。
运行程序,点击按钮,然后使用RE浏览器或者其他的磁盘工具查看本地目录/data/data/packagename/shared_prefs/目录:
2、从SharedPreferences中读取数据
从SharedPreferences读取文件也很简单,SharedPreferences对象中提供了一系列的get方法用于对数据进行读取。每一种get方法都对应了SharedPreferences.Editor中的一种put方法,例如putString()和getString()、putInt()和getInt()、putBoolean()和getBoolean()等等。这些get方法都接收两个参数,第一个参数表示键值,第二个参数为默认值,即传入的键找不到对应的值时,就以默认的值作为返回值。
在刚才的Activity中我们继续做修改,新添加一个按钮用于从SharedPreferences读取数据:
public class PreSharedPreferencesActivity extends BaseActivity {
private Button btn;
private Button btn_load;
private Button btn_pratice;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
btn_load = findViewById(R.id.btn_load_sharedprefs);
btn_load.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences prefs = getSharedPreferences("data", MODE_PRIVATE);
String name = prefs.getString("name", "null");
int age = prefs.getInt("age", 0);
boolean married = prefs.getBoolean("married", false);
Log.d("SharedPreferences", "name: "+ name);
Log.d("SharedPreferences", "age: " + age);
Log.d("SharedPreferences", "married: " + married);
}
});
我们直接看点击事件中的代码。首先,通过getSharedPreferences()方法获得SharedPreferences对象,然后调用其getString()、getInt()、getBoolean()方法获取前面保存下来的数据,并通过Log打印出来。
重新运行程序,点击获取SharedPrefs按钮,观察Logcat:
可以看到,我们很轻松的就把之前存储在SharedPreferences中的数据读取出来了。
关注获取更多内容