一、前提
数据存储的重要程度不言而喻,而且存储的方式也有很多类型,现在就来简介一下
二、目标
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);
效果相同
四、总结
存储很重要,这里仅仅是入手