什么是数据持久化:数据持久化就是指将那些内存中的瞬时数据保存到存储设备中,保证及时在手机或者电脑关机的情况下这些数据仍然不会丢失。保存在内存中的数据处于瞬时状态的。

一:文件存储

不对存储的内容做任何处理,比较适合用于存储一些简单的文本数据或者二进制数据。如果你想使用它保存一些较为复杂的文本数据,就需要自定义一套自己的格式规范。

1:将数据存储到文件中

Context类中提供了一个openFileOutput()方法,可以用于将数据存储到指定的文件中。该方法接收两个参数第一个是文件名不包含路径,因为所有的文件都是默认存储到/data.data//files/目录下的,在文件创建的时候使用的就是这个名字。第二个参数是操作模式,有两种模式可选,MODE_PRIVATE(默认操作模式,表示指定同样文件名时,所写人的内容会覆盖原文件中的内容)和MODE_APPEND(表示该文件已经存在,就往文件里面追加内容,不存在就创建新文件)

//活动中
 private EditText edit;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 edit = (EditText) findViewById(R.id.edit);
 }//重写销毁方法,销毁之前保存数据
 @Override
 protected void onDestroy() {
 super.onDestroy();
 String inputText = edit.getText().toString();
 //save()方法把输入的内容存储到文件中
 save(inputText);
 }//该内部方法把输入内容保存到文件中
 public void save(String inputText){
 String data = “Data to save”;
 //通过该方法得到一个对象
 FileOutputStream out=null;
 BufferedWriter writer =null;
try {
    out=openFileOutput("data", Context.MODE_PRIVATE);
    //通过BufferedWriter来讲文本内容写到文件中
    writer = new BufferedWriter(new OutputStreamWriter(out));
    writer.write(data);
} catch (IOException e) {
    e.printStackTrace();
}finally {
     if(writer!=null){
         try {
             writer.close();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
}

}
@Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 edit = (EditText) findViewById(R.id.edit);
 }//重写销毁方法,销毁之前保存数据
 @Override
 protected void onDestroy() {
 super.onDestroy();
 String inputText = edit.getText().toString();
 //save()方法把输入的内容存储到文件中
 save(inputText);
 }//该内部方法把输入内容保存到文件中
 public void save(String inputText){
 String data = “Data to save”;
 //通过该方法得到一个对象
 FileOutputStream out=null;
 BufferedWriter writer =null;
try {
    out=openFileOutput("data", Context.MODE_PRIVATE);
    //通过BufferedWriter来讲文本内容写到文件中
    writer = new BufferedWriter(new OutputStreamWriter(out));
    writer.write(data);
} catch (IOException e) {
    e.printStackTrace();
}finally {
     if(writer!=null){
         try {
             writer.close();
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
}
}
//布局
<EditTextandroid:id="@+id/edit"s
 android:layout_width=“match_parent”
 android:layout_height=“wrap_content”
 android:hint=“Type something here”
 />

2:从文件中取数据

类似于将数据存储到文件中,Contextl类中还提供了一个openFileInput()方法,用于从文件中读取数据。只接受一个参数,要读的文件名。

//活动中
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 edit = (EditText) findViewById(R.id.edit);
 String inputText = load();
 //该方法进行一次性两次空置的判断,当返回的字符等于空值或者空字符串时这个方法都会返回true
 if(!TextUtils.isEmpty(inputText)){
 edit.setText(inputText);
 edit.setSelection(inputText.length());
 Toast.makeText(this,“Restoring succeeded”,Toast.LENGTH_SHORT).show();
 }
 }//从文档中读方法
 public String load() {
 FileInputStream in = null;
 BufferedReader reader = null;
 StringBuilder content = new StringBuilder();
 try {
 in = openFileInput(“data”);
 reader = new BufferedReader(new InputStreamReader(in));
 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是使用键值对的方式来存储数据的,支持多种不同的数据类型存储。
存储数据类型是字符串,那么取出来的就是字符串,存储的时整型取出来的也是整形。
将数据存储到SharedPreferences来存储数据,首先需要获取到SharedPrederenceS对象。
有三种方法可得到SharedPreferenceS对象。
1.Context类中的getSharedPreferenCes()方法
//接收两个参数第一个参数文件,第二个参数模式

2.Activity类中的getPrefrences()方法
只接受一个参数模式参数,因为使用这个方法时会自动将当前活动的类名作为SharedPreferenceS的文件名。

3.PreferenceManager类中的getDefaultSharedPreferences()方法
静态方法,它接受一个Context参数,并自动使用当前应用程序的报名作为前缀来命名SharePreferenCeS文件。得到对象分为三部实现存储对象。

(1)调用SharedPreferences对象的edit()方法来获取一个SharedPreferenceS.Editor对象。
(2)向SharedPreferenceS.Editor对象中添加数据,添加布尔型数据就的使用putBoolean()方法,添加一个字符串则使用putString()方法。
(3)调用apply()方法将添加的数据提交,完成数据库的存储操作。

@Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 Button saveData=(Button) findViewById(R.id.save_data);
 saveData.setOnClickListener(new View.OnClickListener(){
 @Override
 public void onClick(View view){
 SharedPreferences.Editor editor = getSharedPreferences(“data”,MODE_PRIVATE).edit();
 editor.putString(“name”,“Tom”);
 editor.putInt(“age”,28);
 editor.putBoolean(“married”,false);
 editor.apply();
 }
 });
Button restoreData=(Button) findViewById(R.id.restore_data);
restoreData.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        //取值键第一个参数,第二个参数表示键找不到时会返回默认值
        SharedPreferences preferences = getSharedPreferences("data",MODE_PRIVATE);
        String name = preferences.getString("name","");
        int age = preferences.getInt("age",0);
        boolean married=preferences.getBoolean("married",false);
        Log.d("MainActivity","名字是"+name);
        Log.d("MainActivity","年龄是"+age);
        Log.d("MainActivity","是否结婚"+married);
    }
});


<Button
    android:id="@+id/save_data"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Save data"
    />
<Button
    android:id="@+id/restore_data",
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Restore data"
    />

SQLite数据库存储

是什么:
安卓系统是内置数据库,SQLite是一款轻量级的数据库,运算速度非常快,占用资源也很少,通常只需要几百kb的内存就够了,SQLite不仅支持标准的SQLite语法,还遵循了数据库的ACID事务,十分简单甚至不用设置用户名和密码也可以使用。安卓把这个数据库嵌入到系统中,使得本地持久化功能有了一次质的飞跃。

(1)创建数据库
Android为了让我们能够更加方面地管理数据库,专门提供了一个SQLiteOpenHelper帮助类,该类是一个抽象类,这意味着如果我们要使用他的话,就需要创建一个自己的帮助类去继承它。重写两个抽象方法。
SQLiteOpenHelper中还有两个重要的实列方法:

getReadableDatabase()和getWritableDatabase()
 public class MyDatabaseHelper extends SQLiteOpenHelper {
public static  final String CREATE_BOOK="create table Book("
        + "id integer primary key autoincrement,"
        +"author text,"
        +"price real,"
        +"pages integer,"
        +"name text)";




private Context mContext;

public MyDatabaseHelper(Context context,String name,SQLiteDatabase.CursorFactory factory,int version){
    super(context,name,factory,version);
    mContext=context;
}


@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {

    //调用了SQLiteDatabase的execSQL()执行这条建表语句
    sqLiteDatabase.execSQL(CREATE_BOOK);
    Toast.makeText(mContext,"Create succeeded",Toast.LENGTH_SHORT).show();
}

@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

}
}
主活动代码
 public class MainActivity extends AppCompatActivity {
private MyDatabaseHelper dbHelper;

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


    //第一个参数上下文,第二个参数名字,第三个参数允许我们在查询数据库的时候返回一个自定义的Cursor(光标),一般为空,第四个参数版本号
    dbHelper=new MyDatabaseHelper(this,"BookStore.db",null,1);
    Button createDatabase=(Button) findViewById(R.id.create_database);
    createDatabase.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //getWritableDatabase()可以创建或者打开一个现有的数据库,又打开,没有创建
            dbHelper.getWritableDatabase();
        }
    });
}


<Button
    android:id="@+id/create_database"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Create database"/>
</LinearLayout>

配置platform-tools,目录配置环境变量-系统变量-放入path中
Cmd输入命令 adb shell 进入设备的控制台 使用命令到/data/data/com.example.databasetest/databases/目录下
用ls查看该目录的文件出现两个数据库文件一个自动生成的临时日志,一个是我们创建的
Sqlite命令打开数据库sqlite3 BookStore.db 查看目录数据库有哪些表,键入 .table 命令
查看建表语句 .schema。

数据库升级:5.MyDatabaseHelper中的一个方法onUpgrade(),
public class MyDatabaseHelper extends SQLiteOpenHelper {

public static  final String CREATE_BOOK="create table Book("
        + "id integer primary key autoincrement,"
        +"author text,"
        +"price real,"
        +"pages integer,"
        +"name text)";


public static  final String CREATE_CATEGORY="create table Category ("
        + "id integer primary key autoincrement,"
        +"category_name text,"
        +"category_code integer)";



private Context mContext;

public MyDatabaseHelper(Context context,String name,SQLiteDatabase.CursorFactory factory,int version){
    super(context,name,factory,version);
    mContext=context;
}


@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {

    //调用了SQLiteDatabase的execSQL()执行这条建表语句
    sqLiteDatabase.execSQL(CREATE_BOOK);
    sqLiteDatabase.execSQL(CREATE_CATEGORY);
    Toast.makeText(mContext,"Create succeeded",Toast.LENGTH_SHORT).show();
}

@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    //如果发现这两张表就将这两张表删掉
    sqLiteDatabase.execSQL("drop table if exists Book");
    sqLiteDatabase.execSQL("drop table if exists Category");
    onCreate(sqLiteDatabase);
}
}
 主活动的版本号改为大于原来的1
 //第一个参数上下文,第二个参数名字,第三个参数允许我们在查询数据库的时候返回一个自定义的Cursor(光标),一般为空,第四个参数版本号
 dbHelper=new MyDatabaseHelper(this,“BookStore.db”,null,3);然后再进去查
 命令adb shell
 命令cd /data/data/com.example.databasetest/databases/
 命令ls查看表
 命令sqlite3 加ls中的数据库,进入数据库的编辑
 命令 .table 查看数据库有哪些表
 命令 .schema(图标,纲要方案[s ki me])查看建表语句
 命令.exit命令就可以退出数据库编辑
 6.数据的增删改查
 SQLiteDatabase()方法中有增删改查
 (1)添加数据:
 Button addData=(Button) findViewById(R.id.add_data);
 addData.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View view) {
 SQLiteDatabase sqLiteDatabase=dbHelper.getWritableDatabase();
 ContentValues values=new ContentValues();
 //开始组装第一条数据
 values.put(“name”, “The Da Vinci Code”);
 values.put(“author”,“Dan Brown”);
 values.put(“pages”,132);
 values.put(“price”,16.69);
 //插入第一条数据
 sqLiteDatabase.insert(“Book”,null,values);
 values.clear();//开始组装第二条数据
    values.put("name","第二条数据的名字");
    values.put("author","Dan Brown");
    values.put("pages",500);
    values.put("price",19.96);
    //插入第二条数据
    sqLiteDatabase.insert("Book",null,values);
}});
 (2)更新数据,SQLiteDatabase中的updata()方法。
 //更新数据
 Button updataData=(Button) findViewById(R.id.updata_data);
 updataData.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View view) {
 SQLiteDatabase db=dbHelper.getWritableDatabase();
 ContentValues values=new ContentValues();
 values.put(“price”,1.11);
 //三四个参数据指定更新条件,第三个参数对应的是SQL语句的where部分。表示所有name等于?的行
 //?为一个占位符,可以为第四个参数提供一个字符串为第三个参数中的每个占位符指定相应的内容
 db.update(“Book”,values,“name=?”,
 new String[]{“The Da Vinci Code” });
 Toast.makeText(getApplicationContext(),“更新 succeeded”,Toast.LENGTH_SHORT).show();
 }
 });(3)删除数据
 //删除数据
 Button deleteData=(Button) findViewById(R.id.delete_data);
 deleteData.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View view) {
 SQLiteDatabase db=dbHelper.getWritableDatabase();
 db.delete(“Book”,“pages=?”,new String [] {“132”});
 Toast.makeText(getApplicationContext(),“删除 succeeded”,Toast.LENGTH_SHORT).show();
 }
 });(4)简单查询数据
 query()方法参数 对应SQL部分 描述
 table from table_name 指定查询的表名
 columns select column1, column2 指定查询的列名
 selection where column = value 指定where 的约束条件
 selectionArgs - 为where 中的占位符提供具体的值
 groupBy group by column 指定需要group by 的列
 having having column = value 对group by 后的结果进一步约束
 orderBy order by column1, column2 指定查询结果的排序方式//query简单查询数据
 Button queryButton = (Button) findViewById(R.id.query_data);
 queryButton.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View view) {
 SQLiteDatabase db = dbHelper.getWritableDatabase();
 //查询Book中的所有数据
 Cursor cursor = db.query(“Book”,null,null,null,null,null,null);
 //查询得到的cursor的初始位置是指向第一条记录的前一个位置,一般通过判断cursor.moveToFirst()的值为true或者false来确定查询结果是否为空,将数据的指针移动到数据的第一行位置。
 //cursor.moveToNext()是用来做循环的,和cursor.moveToFirst()方法都可以理解为将数据的指针移动到第一行位置。
 //cursor.moveToPrevious()是指向当前记录的上一个记录,是和moveToNext相对应的;
 //cursor.moveToLast()指向查询结果的最后一条记录
 if(cursor.moveToFirst()){
 do{
 //遍历Cursor对象,取出数据并打印
 //getColumnIndex()方法获取到某一列在表中对应的位置索引,然后将这个索引传入到相应的取值方法中,就可以得到从数据库中读取到的数据了。
 String name = cursor.getString(cursor.getColumnIndex(“name”));
 String author= cursor.getString(cursor.getColumnIndex(“author”));
 int pages = cursor.getInt(cursor.getColumnIndex(“pages”));
 double price=cursor.getDouble(cursor.getColumnIndex(“price”));Log.d("MainActivity","书名"+name);
            Log.d("MainActivity","书的作者"+author);
            Log.d("MainActivity","书的页数"+pages);
            Log.d("MainActivity","书的价格"+price);
        } while(cursor.moveToNext());
    }
    cursor.close();//关闭
}});
使用SQL操作数据库:
 //直接用sql语句来完成增删改查/* 增加
 sqLiteDatabase.execSQL(“insert into Book(name,author,pages,price) values(?,?,?,?)”,new String[] {“The Da Vinci Code”,“Dan Brown”,“454”,“16.96”});
 *//* 更新
sqLiteDatabase.execSQL("update Book set price = ? where name=?, new String[] {"11.11","The Da Vinci Code"});
*/

/*  删除
sqLiteDatabase.execSQL("delete from Book where pages>?", new String[] {"100"});
*/

  /*  查询
  sqLiteDatabase.rawQuery("select * from Book",null);
*/