今天学习第六章
荒废了几天想想还是看书学习吧,没有其他的更好的学习方式了。
还是不看视频学习了。
数据存储全方案——详解持久化技术
Android系统中主要提供了三种方式用于简单地实现数据持久化功能:
1.文件存储
2.SharedPreference存储
3.数据库存储
当然除了这三种方式外,你还可以将数据保存在手机的SD卡中,不过使用文件,SharedPreference或数据库保存数据会相对更简单一些,而且比起将数据保存在SD卡中会更加地安全。
文件存储
适合用于存储一些简单的文本数据或二进制数据。
如果你想使用文件存储的方式来保存一些较为复杂的文本数据,就需要定义一套自己的格式规范,这样可以方便之后需将数据从文件中重新解析出来。
将数据存储到文件中
Context类中提供了一个openFileOutput()方法,用于存储到指定的文件中。
openFileOutput()方法接收两个参数:
第一个参数是文件名,在文件创建的时候使用的就是这个名称,注意这里指定的文件名不可以包含路径,因为所有的文件都是默认存储到/data/data//files/目录下的。
第二个参数是文件的操作模式,主要有两种模式可选,MODE_PRIVATE和MODE_APPEND。
其中MODE_PRIVATE是默认的操作模式,表示当指定同样文件名的时候,所写入的内容将会覆盖原文件中的内容。
而MODE_APPEND则表示如果该文件已存在,就往文件里面追加内容,不存在就创建新文件。
openFileOutput()方法返回的是一个FileOutputStream对象,得到了这个对象之后就可以使用JAVA流的方式将数据写到文件中。
public void save(){
String data = "Data to save";
FileOutputStream out = null;
BufferedWriter writer = null;
try{
out = OpenFileOutput("data",Context.MODE_PRIVATE);
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(data);
}catch(IOException e){
e.printStackTrace();
}finally{
try{
if(writer!=null){
writer.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
}
在这里简单复习一下java流:
1.对文件进行操作:FileInputStream(字节输入流),FileOutputStream(字节输出流),FileReader(字符输入流),FileWriter(字符输出流)
2.Buffered缓冲流::BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter,是带缓冲区的处理流,缓冲区的作用的主要目的是:避免每次和硬盘打交道,提高数据访问的效率。
3.转化流 InputStreamReader/OutputStreamWriter,把字节转化成字符。
从文件中读取数据
类似于将数据存储到文件中,Context类中还提供了一个openFileInput()方法,用于从文件中读取数据.
openFileInput()只接收一个参数,既要读取的文件名,然后系统会自动到/data/data/files/目录下去加载这个文件
并返回一个fileInputStream对象,得到这个对象后再通过Java流的方式就可以将数据读取出来了。
public String load{
FileInputStream in = null;
BufferedReader reader = null;
StringBuilder content = new StringBuilder();
try{
in = OpenFileInput("data");
reader = new BufferedRead(new InputStreamReader(in));
String line = "";
while((line = reader.readline())!= null){
content.append(line);
}
}catch(IOException){
e.printStackTrace();
}finally{
if(reader != null ){
try{
reader.close();
}catch(IOException){
e.printStackTrace();
}
}
}
return content.toString();
}
首先通过openFileInput()方法获取到了一个FileInputStream对象,然后借助它又构建出了一个InputStreamReader对象,接着再使用InputStreamReader构建出一个BufferedReader对象,这样我们就可以通过BufferedReader进行一行行地读取,把文件中所有的文本内容全部读取出来,并存放到一个StringBuilder对象中,最后将读取到的内容返回。
SharedPrefences存储
不同于文件的存储方式,SharePreference是使用键值对的方式来存储数据的。
也就是说,当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在数据读取的时候就可以通过这个键把相应的值取出来。
而且SharePreference还支持多种不同的数据类型存储,如果存储的数据类型是整形,那么读取出来的数据也是整形的。如果存储的数据是一个字符串,
那么读取出来的数据仍然是字符串。
将数据存储到SharePreference
要想使用SharePreference来存储数据,首先需要获取到SharedPreferences对象。
Android中主要提供了3种方法用于得到SharedPreference对象。
1.Context类中的getSharedPreferences()方法
此方法接收两个参数,第一个参数用于指定SharedPreference文件的名称,如果指定的文件不存在则会创建一个,SharePreference文件都是存放在/data/data//shared_prefs/目录下的。
第二个参数用于指定操作模式,目前只有MODE_PRIVATE这一种模式可选,它是默认的操作模式,和直接传入0效果是相同的。表示只有当前的应用程序才可以对这个SharedPreference文件进行读写。
其他的几种模式已经废弃。
2.Activity类中的getPreferences()方法
这个方法和Context中的getSharedPreferences()方法很相似,不过它只接收一个操作参数,因为使用这个方法时会自动将当前活动的类名作为SharedPreference的文件名。
3.PreferenceManager类中的 getDefaultSharedPreference()方法
这是一个静态方法,它接收一个Context参数,并自动使用当前应用程序的包名作为前缀来命名SharedPreference文件,得到了SharedPreference对象之后,就可以开始向SharedPreference文件中存储数据了。
存储数据三步实现:
(1)调用SharedPreference对象的edit()方法来获取一个SharedPreference.Editor对象
(2)向SharedPreference.Editor对象中添加数据,比如添加一个布尔型数据就是用putBoolean()方法,添加一个字符串则使用putString()方法,以此类推。
(3)调用apply()方法将添加的数据提交,从而完成数据存储操作。
例子:
新建一个SharedPrenferenceTest项目,然后修改activity_main.xml中的代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="net.nyist.lenovo.sharedpreferencestest.MainActivity">
<Button
android:id="@+id/btn_SaveData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Save data"
/>
</LinearLayout>
然后修改MainActivity的代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button saveData = (Button) findViewById(R.id.btn_SaveData);
saveData.setOnClickListener(new View.OnClickListener() {
//给按钮注册一个点击事件
@Override
public void onClick(View v) {
SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit();
//指定文件名为data,并且得到SharedPreference.Editor对象。
editor.putString("name","Tom");
editor.putInt("age",18);
editor.putBoolean("married",false);
//添加三个不同类型的数据
editor.apply();
//最后提交
}
});
}
}
从SharedPrenferences中读取数据
SharedPrenferences对象中提供了一系列的get方法,用于对存储的数据进行读取。
每种get方法都对应了SharedPrenferences.Editor中的一种put方法。
这些get方法都接收两个参数:
第一个参数是键,传入存储数据时使用的键就可以得到相应的值了。
第二个参数是默认值,即表示当传入的键找不到对应的值时会以什么样的默认值进行返回。
还是刚才的那个例子:
修改activity_main.xml中的代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="net.nyist.lenovo.sharedpreferencestest.MainActivity">
<Button
android:id="@+id/btn_SaveData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Save data"
/>
<Button
android:id="@+id/restore_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Restore data"
/>
</LinearLayout>
这里增加一个还原数据的按钮,然后修改MainActivity中的代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
······
Button restoreData = (Button) findViewById(R.id.restore_data);
restoreData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences pres = getSharedPreferences("data",MODE_PRIVATE);
//首先通过getSharedPreferences()方法得到了SharedPreferences对象
int age = pres.getInt("age",0);
String name = pres.getString("name","");
boolean married = pres.getBoolean("married",false);
Log.d("MainActivity","name is"+name);
Log.d("MainActivity","age is "+age);
Log.d("MainActivity","married is "+married);
}
});
}
}
下面是结果截图: