4、Android-数据存储方案(文件存储/SharedPreferences)

简介:

任何一个应用程序都需要和数据进行交互

对于软件来说微博、QQ等都需要关系的是数据

没有数据的应用程序是一个没有灵魂的软件

而且还没有实际的用途

可以认为是单机

 

4.1、持久化技术的简介

数据持久化是指将那些内存中的瞬时数据保存到存储设备中

保证手机或者电脑关机的情况下,这些数据不会丢失

 

保存在内存中的数据是处于瞬时状态

保证再存储设备中的是处于持久状态

持久化技术则提供了一种机制可以让数据再瞬时状态持久化状态之间进行转换

 

持久化技术被广泛应用于各种程序设计的领域当中

Android系统中主要提供了3中方式用于简单地实现数据持久化功能

文件存储SharePreference存储以及数据库存储

 

还可以将数据保存在手机的SD卡中

使用文件、SharePreference或者数据库保存文件会更简单一点

数据存放也比再SD卡中更见安全

 

 

4.2文件存储

文件存储是Android中最基本的一种数据存储方式

不对存储的内容进行任何的格式化处理

所有的数据都是原封不动的保存再文件当中

比较适合用于存储一些简单的文本数据或者二进制数据

若需要使用文件存储的方式来保存一些较为复杂的文本数据,需要定义一套自己的格式规范

方便将文件数据从文件中解析出来

 

4.2.1、将数据存储到文件中

Context类中提供了一个openFileOutput()方法,可以用于将数据存储到指定的文件中

两个参数:

1、文件名,再文件创建的时候使用就是这个名称

  注意:这指定的文件名不包含路径,所有文件都是默认存储再data/data/<packagename>/files目录下

2、文件操作的模式,两种模式MODE_PRIVATE和MODE_APPEND

  前者是默认的操作模式,表示当前指定同样的文件的名的时候,所写入的内容将会覆盖原有的内容

  后者是表示该文件已存在时,对原文件进行内容的追加不存在就创建新的文件

文件的操作模式还有两种:

MODE_WORLD_READDABLE、MODE_WORLD_WRITEABLE

这两种模式允许其他的应用程序对我们程序中的文件进行读写操作

不过由于这两种模式过于危险、很容易引起应用的安全性漏洞,再4.2版本中废弃

 

openFileOutput()方法返回是一个FileOutputStream对象

这个对象就可以使用Java流的方式将数据写到文件中

 

xml布局:

first_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入数据"
        android:id="@+id/edit"/>
    <Button
        android:id="@+id/button_sengs"
        android:text="button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

 

 

MainActivity中:

public class MainActivity extends AppCompatActivity {

    private EditText editText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.first_layout);
        editText = (EditText) findViewById(R.id.edit);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        String date = editText.getText().toString();
        save(date);
    }

    //保存方法
    public  void save(String data){

        FileOutputStream outputStream = null;
        BufferedWriter bufferedWriter = null;

        try {
            outputStream = openFileOutput("data.txt",MODE_PRIVATE);
            bufferedWriter=new BufferedWriter(new OutputStreamWriter(outputStream));
            bufferedWriter.write(data);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (bufferedWriter != null){
                    bufferedWriter.close();
                }else if (outputStream != null){
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

sava()方法用于保存数据的方法

这里通过openFileOutput()方法可以得到一个FileOutoutStream对象

再构建一个OutputStreamWriter对象

接着再使用OutputStreamWriter构建处一个BufferedWriter对象

此时可以通过BufferedWriter将内容写道数据中

 

在文本框中输入上数据

在点击Back键返回查看数据是否保存在文件中:

4、Android-数据存储方案(文件存储/SharedPreferences)

使用开发工具提供的工具进行查看文件:

4、Android-数据存储方案(文件存储/SharedPreferences)

然后点击:

4、Android-数据存储方案(文件存储/SharedPreferences)

找到文件位置:

/data/data/com.example.ccrr.applicationtwo/file/目录

此时可以看到一个名为data的文件:

4、Android-数据存储方案(文件存储/SharedPreferences)

将文件导入到电脑上进行查看:

4、Android-数据存储方案(文件存储/SharedPreferences)

查看文件内容:

4、Android-数据存储方案(文件存储/SharedPreferences)

此时点击Back键返回退出程序的文本框内容就会保存到文件中

 

 4.2.2、从文件中读取数据

Context类提供了一个openFileInput()方法

用于从文件中读取数据

只接受一个参数:读取文件的文件名

系统会自动在/data/data/<package name>/files/目录下去加载这个文件

并且返回一个FileImputtream对象

这个对象可以通过java流的方式将数据读取出来

 

在MainActivity中:

public class MainActivity extends AppCompatActivity {

    private EditText editText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.first_layout);
        editText = (EditText) findViewById(R.id.edit);
    }

    @Override
    protected void onResume() {
        super.onResume();
        Button button = (Button) findViewById(R.id.button_sengs);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String text  = readDate();
                if (!TextUtils.isEmpty(text)){
                    Log.i("text", text);
                    editText.setText(text);
                    Toast.makeText(MainActivity.this,text.toString(),Toast.LENGTH_LONG).show();
                }
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        String date = editText.getText().toString();
        save(date);
    }

    //保存方法
    public  void save(String data){
        //String data = "保存的数据";
        FileOutputStream outputStream = null;
        BufferedWriter bufferedWriter = null;

        try {
            outputStream = openFileOutput("data.txt",MODE_PRIVATE);
            bufferedWriter=new BufferedWriter(new OutputStreamWriter(outputStream));
            bufferedWriter.write(data);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (bufferedWriter != null){
                    bufferedWriter.close();
                }else if (outputStream != null){
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
//读取数据 public String readDate(){ FileInputStream in = null; BufferedReader reader = null; StringBuffer context = new StringBuffer(); try { in = openFileInput("data.txt"); reader = new BufferedReader(new InputStreamReader(in)); String line =""; while ((line = reader.readLine())!=null){ Log.d("line", line); context.append(line); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { try { if(reader != null){ reader.close(); }else if (in != null){ in.close(); } } catch (IOException e) { e.printStackTrace(); } }return context.toString(); } }

在readDate()方法中

首先通过openFileInput()方法得到一个FileInputStream对象

然后借助它构建了一个InputStreamReader对象

接着使用InputStreamReader构建处一个BufferedReader对象

可以通过BufferedReader进行一行一行的读取

此时将读取到的内容存放在StringBuilder对象中

 

重启工程:点击按钮可以得到

4、Android-数据存储方案(文件存储/SharedPreferences)

         if (!TextUtils.isEmpty(text)){
                    Log.i("text", text);
                    editText.setText(text);
                    editText.setSelection(text.length());
                    Toast.makeText(MainActivity.this,text.toString(),Toast.LENGTH_LONG).show();
                }

 这里也可以使用setSelection()方法将输入光标移动到文本末尾位置以便继续输入

 

总结:

核心技术就是Context类中提供的openFileInput()和openFileOutput()方法

之后就是利用java的各种流来进行读写操作

文件存储的方式并不适用于保存一些较为复杂的文本数据

 

4.3、SharedPreferences存储

不同于文件的存储方式

SharedPreferences是使用键值对的方式来存储数据的

当保存一条数据的时候,需要给这条数据提供一个对应的键

在读取数据数据的时候就可以通过这个把相应的值取出来

 

SharedPreferences还支持多种不同的数据类型

如果存储的数据类型是整形,那么读取出来的数据也是整形

存储数据是字符串,读取的数据仍然是字符串

 

4.3.1、将数据存储到SharedPreferences中

若要使用SharedPreferences来存储数据

首先需要获取到SharedPreferences对象

Android中提供了3中主要的方法得到SharedPreferences对象

1、Context类中getSharedPreferences()方法

该方法有两个参数

参数一:SharedPreferences文件名称,文件不存在会创建一个文件都是存放在

    /data/data/<package name>/shared_prefs/目录下

参数二:用于指定操作模式,目前只有MODE_PRIVATE这一种模式可选,是默认的操作模式

    和直接传入0效果相同,表示只有当前的应用程序才可以对这个SharedPreferences文件进行读写

    其余的集中操作模式在4.2版本和6.0版本中被废弃

2、Activity类中的getPreferences()方法

和Context中的getSharedPreferences()方法类似

不过他只是接受一个操作模式参数

因此使用这个方法时会自动将当前活动的类名作为SharedPreferences的文件名

3、PreferenceManager类中的getDefaultSharedPreferences()方法

这是一个静态的方法,接受一个Context参数

并且自动使用当前应用程序的包名作为前缀来命名SharedPreferences文件

得到了SharedPreferences对象之后,就可以开始向SharedPreferences文件中存储数据

分为以下3部:

①、调用SharedPreferences对象edit()方法来获取一个SharedPreferences.Editor对象

②、向SharedPreferences.Editor对象中添加数据,添加布尔值就是用putBoolean()方法。字符串则是

  putString()方法,类推......

 

③、调用apply()方法将添加的数据提交,从而完成数据存储

 

测试:MainActivity中

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onResume() {
        super.onResume();
        Button button = (Button) findViewById(R.id.button_sengs);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                SharedPreferences.Editor editor = 
            getSharedPreferences("data",MODE_PRIVATE).edit(); editor.putString("name","MrChengs"); editor.putInt("age",22); editor.putBoolean("married",false); editor.apply(); } }); } }

这里的点击事件

通过点击事件保存数据

点击事件通过getSharedPreferences()方法来指定SharedPreferences的文件名为data

得到了SharedFerences.Editor对象

接着在对象中添加3条不同类型的数据

最后使用apply()方法进行提交

从而完成了数据的存储操作

 

运行程序点击按钮:

此时查看文件:

此时查看数据的存储方式

4、Android-数据存储方案(文件存储/SharedPreferences)

SharedPerferences文件使用XML文件格式对数据继续宁管理的

 

 4.3.2、从SharedPreferences中读取数据

上文中的测试使用SharedPerferences来存储数据时非常简单的

从中读取文件的方法也是非常简单的的

SharedPerferences对象中提供了一系列的get()方法

用于对存储数据进行读取

每种get方法都对应了SharedPreferences.Editor中的一种put方法

这些get方法都接受两个参数:

参数一:键,传入存储数据使用的键就可以得到相应的值

参数二:默认值,即表示当传入了键找不到对应的值会以什么样的默认值进行返回

 

在MainActivity

 protected void onResume() {
        super.onResume();
        Button button = (Button) findViewById(R.id.button_sengs);

        Button button_data  = (Button) findViewById(R.id.button_get);
        //得到数据
        button_data.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferences p = getSharedPreferences("data",MODE_PRIVATE);
                String name = p.getString("name","Mr");
                int age = p.getInt("age",0);
                Boolean married = p.getBoolean("married",true);

                Log.d("name",name );
                Log.d("age", String.valueOf(age));
                Log.d("married", String.valueOf(married));
            }
        });

        //添加数据
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit();
                editor.putString("name","MrChengs");
                editor.putInt("age",22);
                editor.putBoolean("married",false);
                editor.apply();

            }
        });
    }

 

首先通过getSharedPerferences()方法得到了SharedPreFerences对象

然后分别调用它的getString()、getInt()、getBoolean()等方法来获取存储的值

如果没有获取到的值,就会返回默认值

 

 first_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入数据"
        android:id="@+id/edit"/>

    <Button
        android:id="@+id/button_sengs"
        android:text="button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/button_get"
        android:text="get data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

 

4、Android-数据存储方案(文件存储/SharedPreferences)

点击按钮查看后台的打印情况:

4、Android-数据存储方案(文件存储/SharedPreferences)

 

 4.3.3、实现记住密码功能

 

4、Android-数据存储方案(文件存储/SharedPreferences)

上一篇:移动端有哪些常见布局方式?


下一篇:利用 Charles Proxy 下载旧版本 iOS App