Android Studio开发学习(十五)——数据存储

一、前提

数据存储的重要程度不言而喻,而且存储的方式也有很多类型,现在就来简介一下

二、目标

1、SharedPreferences 轻量数据存储,通过键值对中存储私有原始数据

2、File文件

三、内容

1、SharedPreferences 轻量数据存储

在xml文件中添加一个编辑框,两个按钮和一个文本框,作用是当我们在编辑框输入信息时,点击保存按钮后将信息保存,再点击显示按钮将保存的内容显示到文本框中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context="com.example.sunny.sharedpreferences.Sharedpreference">

    <EditText
        android:id="@+id/name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入内容"
        />

    <Button
        android:layout_marginTop="10dp"
        android:id="@+id/save"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="save"
        />

    <Button
        android:layout_marginTop="10dp"
        android:id="@+id/show"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="show"
        />

    <TextView
        android:layout_marginTop="10dp"
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

在MainActivity中添加

package com.example.sunny.sharedpreferences;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class Sharedpreference extends AppCompatActivity {

    private Button button1,button2;
    private TextView textView;
    private EditText editText;
    private SharedPreferences sharedPreferences;
    private SharedPreferences.Editor editor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sharedpreference);

        button1= (Button) findViewById(R.id.save);
        button2= (Button) findViewById(R.id.show);
        textView= (TextView) findViewById(R.id.tv);
        editText= (EditText) findViewById(R.id.name);

        sharedPreferences=this.getSharedPreferences("data",MODE_PRIVATE);//通过getSharedPreferences()实例化。两个参数是文件名和模式,模式下MODE_PRIVATE是最常用的,其余的很少用
        editor=sharedPreferences.edit();

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                editor.putString("name",editText.getText().toString());
                editor.apply();
            }
        });

        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText(sharedPreferences.getString("name",""));
            }
        });

    }
}

代码其实不难,除了常见的几个按钮的代码,还有定义存储数据的方法,其中SharedPreferences.Editor,表示接口,用于修改SharedPreferences对象中的值。您在编辑器中所做的所有更改都是成批处理的,并且在调用commit或apply之前不会复制回原始的SharedPreferences。意思就是通过它来保存

edit()表示为这些首选项创建一个新的编辑器,通过这个编辑器,您可以修改首选项中的数据,并自动地将这些更改提交回SharedPreferences对象。

editor.putString()中的两个参数是key和value,当然还有许多的方法可以用putInt(),putLong(),putFloat()等等,看各自的需要

apply()相当于提交,相比于commit来说在此方法中使用更多的就是apply()因为它相当于异步操作

这两个方法的区别在于: 
(1)apply没有返回值而commit返回boolean表明修改是否提交成功 
(2)apply是将修改数据原子提交到内存, 而后异步真正提交到硬件磁盘, 而commit是同步的提交到硬件磁盘,因此,在多个并发的提交commit的时候,他们会等待正在处理的commit保存到磁盘后在操作,从而降低了效率。而apply只是原子的提交到内容,后面有调用apply的函数的将会直接覆盖前面的内存数据,这样从一定程度上提高了很多效率。 
(3)apply方法不会提示任何失败的提示。 
由于在一个进程中,sharedPreference是单实例,一般不会出现并发冲突,如果对提交的结果不关心的话,建议使用apply,当然需要确保提交成功且有后续操作的话,还是需要用commit的。

最后的按钮点击后显示文本

 

2、File java的io流,这里要对java相对来说熟悉一些

(1)内部存储,是在应用的安装目录下,将之前的代码改为


package com.example.sunny.sharedpreferences;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class File extends AppCompatActivity {

    private Button button1,button2;
    private TextView textView;
    private EditText editText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_file);

        button1= (Button) findViewById(R.id.save);
        button2= (Button) findViewById(R.id.show);
        textView= (TextView) findViewById(R.id.tv);
        editText= (EditText) findViewById(R.id.name);


        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                save(editText.getText().toString());
            }
        });

        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText(read());
            }
        });

    }

    //存储数据
    private void save(String content){
        FileOutputStream fileOutputStream=null;
        try {
            fileOutputStream=openFileOutput("text.txt",MODE_PRIVATE);
            fileOutputStream.write(content.getBytes());
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fileOutputStream!=null){
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //读取数据
    private String read(){
        FileInputStream fileInputStream=null;
        try {
            fileInputStream=openFileInput("text.txt");
            byte[] buff=new byte[1024];//计算机处理数据的单位就是字节,读取文件的1024字节长度的信息,byte数组相当于缓存,要循环去进行读写的
            StringBuilder stringBuilder=new StringBuilder("");//用来拼接,StringBuffer是线程安全的,而StringBuilder则没有实现线程安全功能,所以性能略高
            int len=0;
            while((len=fileInputStream.read(buff))>0){
                stringBuilder.append(new String(buff,0,len));//从0到len读取的1024个字节,直到text.txt文件中的数据读完
            }
            return stringBuilder.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fileInputStream!=null){
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

运用到了java的输入输出流,都是java中基本知识,在这里不做赘述,效果与上图一样

(2)外部存储,相当于SD卡,代码相同,只是路径不同,原理相仿

package com.example.sunny.sharedpreferences;

import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileActivity extends AppCompatActivity {

    private Button button1,button2;
    private TextView textView;
    private EditText editText;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_file);

        button1= (Button) findViewById(R.id.save);
        button2= (Button) findViewById(R.id.show);
        textView= (TextView) findViewById(R.id.tv);
        editText= (EditText) findViewById(R.id.name);


        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                save(editText.getText().toString());
            }
        });

        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText(read());
            }
        });

    }

    //存储数据
    private void save(String content){
        FileOutputStream fileOutputStream=null;
        try {
//            fileOutputStream=openFileOutput("text.txt",MODE_PRIVATE);
            // 新建文件夹
            File dir=new File(Environment.getExternalStorageDirectory(),"skypan");
            if(!dir.exists()){
                dir.mkdirs();
            }
            //新建文件
            File file=new File(dir,"text.txt");
            if(!file.exists()){
                file.createNewFile();
            }
            fileOutputStream=new FileOutputStream(file);
            fileOutputStream.write(content.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fileOutputStream!=null){
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //读取数据
    private String read(){
        FileInputStream fileInputStream=null;
        try {
//            fileInputStream=openFileInput("text.txt");
            File file=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"skypan","text.txt");//通过路径找文件
            fileInputStream=new FileInputStream(file);
            byte[] buff=new byte[1024];//计算机处理数据的单位就是字节,读取文件的1024字节长度的信息,byte数组相当于缓存,要循环去进行读写的
            StringBuilder stringBuilder=new StringBuilder("");//用来拼接,StringBuffer是线程安全的,而StringBuilder则没有实现线程安全功能,所以性能略高
            int len=0;
            while((len=fileInputStream.read(buff))>0){
                stringBuilder.append(new String(buff,0,len));//从0到len读取的1024个字节,直到text.txt文件中的数据读完
            }
            return stringBuilder.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fileInputStream!=null){
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

在Manifest文件中添加权限

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

最后如果API再23以上,要在MainActivity中添加,申请权限

ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);

效果相同

四、总结

存储很重要,这里仅仅是入手

  • 8
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值