SaveData-android储存数据

SaveData-android储存数据

简述

对于一个App而言,对数据的储存肯定是必不可少的,根据数据的不同,也应该使用不同的储存方式,就android而言,基础的有以下5种方式储存数据:

  1. SharedPreferences
  2. 写入文件中
  3. 数据库
  4. contentProvider
  5. 写入云端

一一讲解

一.SharedPreferences

  1. SharedPreferences是Android平台上一个轻量级的存储类,主要是保存一些常用的配置比如窗口状态,比如在Activity中重载窗口状态onSaveInstanceState保存一般使用SharedPreferences完成,它提供了Android平台常规的Long长 整形、Int整形、String字符串型的保存,它的本质是基于XML文件存储key-value键值对数据,其存储位置在/data/data/<包名>/shared_prefs目录下。
  2. 支持类型:boolean,int,float,long和String五种简单的数据类型
  3. 使用
        Context context = MainActivity.this;
        SharedPreferences sp = context.getSharedPreferences("sp", MODE_PRIVATE);//建议使用全局context来获取
        SharedPreferences.Editor edit = sp.edit();
        edit.putInt("A",1);
        edit.putBoolean("B",true);
        edit.putFloat("C",1.0f);
        edit.putLong("D", 2L);
        edit.putString("E","String");
        edit.apply();//使用apply提交事务

二.写入文件

  1. Activity提供了openFileOutput()方法可以用于把数据输出到文件中,具体的实现过程与在J2SE环境中保存数据到文件中是一样的。
  2. 使用(这里可以参考java文件操作,后面附链接)
  public void saveData(){
        try {
        FileOutputStream outputStream = this.openFileOutput("a.txt",Context.MODE_PRIVATE);
            outputStream.write("A".getBytes());
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

penFileOutput()方法的第二参数用于指定操作模式,有四种模式,分别为:

Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,

在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可以使用Context.MODE_APPEND

Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。

Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用来控制其他应用是否有权限读写该文件。

MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;

MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。

  1. 另外,在使用文件储存的时候一般写在sdCard内,这个还需要申请权限

三.数据库

1. SQLite轻量级数据库

1.1 简洁
SQLite是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入 式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持 Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如Tcl、PHP、Java、C++、.Net等,还有ODBC接口,同样比起 Mysql、PostgreSQL这两款开源世界著名的数据库管理系统来讲,它的处理速度比他们都快。
1.2 使用
这点就不写了,学习学习SQlite语句就差不多了,事实上,目前android应用上,这个已经几乎是不被使用了,可参考跳转至SQLite详解

2. Room数据库

目前的主流数据库之一,从greenDao演变而来

  1. 使用:
    导包:
    //room
    def room_version="2.4.2"
    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"
    //implementation "androidx.room:room-rxjava2:$room_version"
    //implementation "androidx.room:room-rxjava3:$room_version"
    //implementation "androidx.room:room-guava:$room_version"
    //testImplementation "androidx.room:room-testing:$room_version"
    //implementation "androidx.room:room-paging:2.5.0-alpha01"

第一步:创建映射实体类
创建实体类,这个实体类就是数据库映射的接受类,对应的是数据库的user表,可以将数据库的表结构映射成Java Bean。使用注解标记相应的功能,通过名字就可以非常清楚的知道。
@Entity 表结构实体
@PrimaryKey 主键
@ColumnInfo 列/字段信息

package com.example.singleton.age;

import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;

@Entity
public class Student{
    @PrimaryKey
    private int id;

    @ColumnInfo
    private String name;

    @ColumnInfo
    private int age;
    
}

第二步:创建Dao接口
创建我们的Dao接口,这种实现方式和Retrofit是非常相似的。其实最感觉的就是SQL语句。这里我们先只关系getAll这个方法就行,语句是最简单的"SELECT * FROM user"。
对应的注解也是非常容易理解,分别对应增删改查。

@ Query 查询
@ Delete 删除
@ Update 修改
@ Insert 插入

package com.example.singleton.age;

import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;

import java.util.List;

@Dao
public interface StudentDao {
    @Insert
    void insertStudent(Student student);

    @Insert
    void insertAllStudents(Student... students);

    @Delete
    boolean deleteStudent();

    @Delete
    boolean deleteAllStudents();

    @Query("SELECT * FROM student")
    List<Student> getAll();

    @Query("SELECT * FROM Student WHERE id IN(:id)")
    List<Student> getStudentById(int id);

    @Update
    void update(int id,Student student);
}

第三步:创建数据库抽象接口
需要继承RoomDatabase,通过@Database指定需要创建的表。还可以指定版本。

package com.example.singleton.age;

import androidx.room.Database;
import androidx.room.RoomDatabase;

@Database(entities = {StudentDao.class},version = 1)
public abstract class StudentDataBase extends RoomDatabase {
    public abstract StudentDao studentDao();
}

第四步:调用数据库

 StudentDataBase dataBase = Room.databaseBuilder(getApplicationContext(), StudentDataBase.class, "stu.db").build();
  1. 数据库迁移
    自动迁移
    Room,当字段有变化,按照前面的使用方法添加删除某字段,即可完成自升级,当然改了字段同时得加版本。
    操作也很简单,如果两个版本之间自动迁移,需要在 @Database 注解中的 autoMigrations 参数中添加一个 @AutoMigration 注解即可。

如果 Room 发现迁移过程中有歧义,并且在未提供更多信息的时候无法制定确切的自迁移方案,在编译期间就会发生错误,这时开发者需要提供一个 AutoMigrationSpec 的实现。多数情况下,自迁移发生错误都是由下列的原因造成的。

删除或者重命名数据表名
删除或者重命名数据表的列名
对于这种编译错误,开发者可以定义一个 AutoMigrationSpec 对象,给Room准确地生成迁移路径提供必要的额外信息。在 RoomDatabase 内部定义一个 AutoMigrationSpec 实现类,并且用以下注解进行标注。

@DeleteTable:删除数据表 @RenameTable: 重命名数据表 @DeleteColumn:删除数据表中的列 @RenameColumn:重命名数据表中的列
在自动迁移数据库时使用 AutoMigrationSpec 实现类,只需要在 @AutoMigration 注解的 spec 参数中指定即可。如果应用需要在自动迁移完成之后做更多的操作,可以重写 onPostMigrate() 方法并在内部实现需要进行的操作,Room 会在自动迁移完成之后调用这个方法。如下示例所示:

                                    //version升级为2
@Database(entities = {Student.class}, version = 2,autoMigrations = {@AutoMigration(from = 1,to = 2)})
public abstract class StudentDataBase extends RoomDatabase {
    public abstract StudentDao studentDao();

    static final Migration MIGRATION_1_2 = new Migration(1,2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
        	//执行sql语句,表示增加字段sex
            database.execSQL("ALTER TABLE sex ADD COLUMN duration INTEGER NOT NULL DEFAULT 0");
        }
    };
}

相应的entities和Dao也需要做更改,具体可以参考数据库升级

注意: Room 自动迁移是基于新版和旧版生成的数据库架构的,如果 @Database 的 exportSchema 设置为 false,(这里为false,系app一开始就没规划好导致,故无法验证示例代码,若你们的版本是2.4.0以后的,可以是尝试下自动迁移带来的便利),或者没有提升Room的版本号就进行编译,自动迁移操作将会失败。

四.contentProvider

跳转至contentProvider使用
参考跳转至contentProvider

五.网络储存

这个比较简单,就不详细介绍。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值