持久化技术
数据持久化指的是那些内存中的瞬时数据保存再存储设备中,即使在手机关机断电也不会丢失。android系统中主要提供了3种方式简单地实现数据持久化功能,文件储存、SharedPreference存储以及数据库储存,还有一种是SD卡的,这里先不说
将数据储存到文件中
Context类中提供了openFileOutPut()方法,可以将数据存储到指定的文件夹
这个方法接受两个参数,第一个参数是文件名(注意不包含路径),第二是文件操作模式(默认是MODE_PRIVATE,当存在同样文件夹名字的时候,会覆盖原有内容
接下来直接上案例:
首先新建一个项目,并在actiity_main.xml中添加一个EditText,这样有助于我们修改储存的内容
<LinearLayout xmlns:android="http://schems.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_partent"
android:layout_height="match_partent">
<EditText
android:id="@+id/edit"
android:layout_width="match_partent"
android:layout_height="warp_content"
/>
</LinearLayout>
我们输入在EditText里面的数据都是瞬时数据,如果不保存起来,下一次打开的时候就已经丢失了,所以我们修改MainActivity中的代码
public class MainActivity extends AppCompatActivity {
private EditText edit;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit = (EditText) findViewById(R.id.edit);
}
//在前台活动摧毁之前把数据保存到文件里面
protected void onDestroy(){
super.onDestroy();
String inputText = edit.getText().toString();
//在活动关闭的时候调用
save(inputText);
Log.d("file","你输出了"+inputText);
}
public void save(String inputText){
FileOutputStream out = null;
BufferedWriter writer = null;
try{
//首先通过openFileOutput得到一个FileOutPutStream对象
//再借助它构建出一个OutputStreamWriter对象
//再通过OutputStreamWriter构建出一个BufferedWrite
//再通过BufferedWrite将文本写入文件
out = openFileOutput("data",Context.MODE_PRIVATE);
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(inputText);
}catch(IOException e){
e.printStackTrace();
}finally{
try{
if(writer != null){
writer.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
}
}
然后运行app,在输入框输入内容,并关闭软件,就会自动保存数据并储存
打开/data/data/<包名>/files/目录下就会看到刚刚生产的data文件,打开就可以看到我们刚刚输入的内容

读取文件中的数据
类似文件存储,Context中还提供了一个openFileInput()的方法来用于从文件读取数
它接收一个参数就是要读取的文件名
我们接着上面的案例继续写,我们把刚刚存储的数据从新放回EditText里面
在onCreate中添加:
String inputText = load();
//调用load()方法,如果读到的内容不为空,就settext
if(!TextUtils.isEmpty(inputText)){
edit.setText(inputText);
edit.setSelection(inputText.length());
Toast.makeText(this,"恢复数据",Toast.LENGTH_SHORT).show();
}
load()方法:
public String load(){
//注意它是要返回一个String的
//首先通过openFileInput获取一个FileInputStream对象,
//然后借助它构建一个InputStreamReader对象
//再使用构建一个BufferedReader对象
FileInputStream input = null;
BufferedReader reader = null;
StringBuilder content = new StringBuilder();
try{
input = openFileInput("data");
reader = new BufferedReader(new InputStreamReader(input));
String line = "";
while((line = reader.readLine()) != null){
content.append(line);
}
}catch(IOException e){
e.printStackTrace();
} finally {
if(reader != null){
try{
reader.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
return content.toString();
}
它就回去读取文件中的值,并放回去

SharedPreferences存储
SharedPreferences存储是使用键值对的方式存储的,类似于key-value,当你需要取出一条数据的时候,需要给他相应的键再取出相应的值,而且SharedPreferences存储还支持区分数据类型存储。
如何获取SharedPreferences
Android提供了3中方法获取SharedPreferences对象。
1) Context 类中的 getSharedPreferences()方法
参数:getSharedPreferences()需要如下两个参数
String类型:指定文件名(不需要带文件后缀)
int类型:指定文件的操作模式,常用的是MODE_PRIVATE (该文件只允许本应用程序进行读写),MODE_APPEND(对文件进行写入操作时,是在文件尾追加内容),MODE_MULTI_PROCESS (用于会有多个进程中对同一个 SharedPreferences 文件进行读写的情况)。
2) Activity 类中的 getPreferences()方法
参数:只接收一个操作模式参数。
这个方法时会自动将当前活动的类名作为 SharedPreferences 的文件名。
3) PreferenceManager 类中的 getDefaultSharedPreferences()方法
这是一个静态方法,它接收一个 Context 参数,并自动使用当前应用程序的包名作为前缀来命名 SharedPreferences 文件
其实简单来说:
获取Preferences对象
preferences = getSharedPreferences("acount_login",MODE_PRIVATE);
存储用户登录的信息
//获取editor对象
SharedPreferences.Editor editor = preferences.edit();
//存储数据时选用对应类型的方法
editor.putString("userId",user.getUserId());
editor.putString("username",user.getUserName());
editor.putString("password",user.getPassword());
//提交保存数据
editor.commit();
取出数据(取出数据之前要先获得SharedPreferences对象)
//取出数据,第一个参数是存取的键,第二个参数-->如果该key不存在,返回默认值,这里返回的默认值是""
String userId = preferences.getString("username","");
String password = preferences.getString("password","");
接下来是展示:
首先创建一个新项目,并修改布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="match_parent"
android:layout_width="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="账户:"
/>
<EditText
android:id="@+id/account"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="8"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="密码:"
/>
<EditText
android:id="@+id/password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="8"
android:inputType="textPassword"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/remember"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#03A9F4"
android:text="记住密码" />
<Button
android:id="@+id/rec"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="恢复数据"
/>
</LinearLayout>
</LinearLayout>

然后修改mainActivity文件:
package com.example.sharedpreferencestest;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
private EditText accountEdit;
private EditText passwordEdit;
private Button remember;
private Button rec_button;
private SharedPreferences pref;
private SharedPreferences.Editor editor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
accountEdit = (EditText)findViewById(R.id.account);
passwordEdit = (EditText) findViewById(R.id.password);
remember = (Button) findViewById(R.id.remember);
rec_button = (Button) findViewById(R.id.rec);
pref = PreferenceManager.getDefaultSharedPreferences(this);
//也可以直接pref = getSharedPreferences("data",MODE_PRIVATE);
//把数据导回EditTest
rec_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String account = pref.getString("account","");
String password = pref.getString("password","");
accountEdit.setText(account);
passwordEdit.setText(password);
}
});
//点击记住的按钮
remember.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
editor = pref.edit();
editor.putString("account",accountEdit.getText().toString());
editor.putString("password",passwordEdit.getText().toString());
editor.apply();
}
});
//点击恢复按钮
}
}
这样,点击左边的按钮就会把数据存储到文件里面去,关闭软件并再点击右边的按钮就会恢复数据并自动放到对应的位置。