当前位置:首页 > 行业动态 > 正文

安卓开发数据获取和存储方法

数据存储方式

SharedPreferences(轻量级键值对)

  • 用途:存储简单配置项(如用户偏好、登录状态)

  • 特点

    • 基于XML文件存储
    • 支持putString()/getString()等基础数据类型
    • 自动生成文件名(默认app_name_preferences
  • 示例代码

    // 写入数据
    SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
    sp.edit().putBoolean("isLoggedIn", true).apply();
    // 读取数据
    boolean loggedIn = sp.getBoolean("isLoggedIn", false);
  • 优缺点
    | 特性 | 说明 |
    |————–|——————————|
    | 存储容量 | 仅支持KB级小数据 |
    | 访问速度 | 极快(内存级操作) |
    | 数据类型 | 仅限基础数据类型 |
    | 适用场景 | 用户偏好设置、临时状态保存 |

文件存储(原始文件操作)

  • 用途:存储非结构化数据(如JSON配置文件、图片缓存)

  • 特点

    • 需手动管理文件路径(getFilesDir()/getExternalFilesDir()
    • 支持MODE_APPEND/MODE_PRIVATE等文件模式
  • 示例代码

    // 写入文本文件
    try (FileOutputStream fos = openFileOutput("data.txt", MODE_PRIVATE)) {
        fos.write("Hello World".getBytes());
    }
    // 读取文件
    try (BufferedReader br = new BufferedReader(new FileReader(getFilesDir()+"/data.txt"))) {
        String line = br.readLine();
    }
  • 优缺点
    | 特性 | 说明 |
    |————–|——————————|
    | 存储容量 | 受限于设备存储空间 |
    | 访问速度 | 较慢(IO操作) |
    | 数据格式 | 需自行处理序列化/反序列化 |
    | 适用场景 | 配置文件保存、日志记录 |

    安卓开发数据获取和存储方法  第1张

SQLite数据库(结构化存储)

  • 用途:存储复杂关系型数据(如用户信息表、订单记录)

  • 特点

    • 通过SQLiteOpenHelper管理版本升级
    • 支持事务操作(beginTransaction()
  • 示例代码

    // 创建表
    SQLiteDatabase db = helper.getWritableDatabase();
    db.execSQL("CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY, name TEXT)");
    // 插入数据
    ContentValues cv = new ContentValues();
    cv.put("name", "John");
    db.insert("users", null, cv);
  • 优缺点
    | 特性 | 说明 |
    |————–|——————————|
    | 存储容量 | GB级(受限于设备存储) |
    | 查询效率 | 高(SQL优化) |
    | 开发成本 | 需处理建表/升级/索引 |
    | 适用场景 | 业务数据持久化 |

Room持久化库(SQLite封装)

  • 用途:简化SQLite操作,提供编译时校验

  • 特点

    • 通过@Entity/@Dao注解定义数据结构
    • 支持LiveData观察数据变化
  • 示例代码

    @Entity
    public class User {
        @PrimaryKey(autoGenerate = true)
        public int id;
        public String name;
    }
    @Dao
    public interface UserDao {
        @Insert
        void insert(User user);
        @Query("SELECT  FROM User")
        List<User> getAll();
    }
  • 优势

    • 避免手写SQL语句
    • 线程安全的数据访问
    • 自动生成数据库迁移脚本

ContentProvider(跨应用数据共享)

  • 用途:公开自有数据给其他应用(如通讯录数据)
  • 特点
    • 通过URI标识数据(如content://contacts/people
    • 需实现query()/insert()等抽象方法
  • 示例代码
    // 查询联系人
    Uri uri = Uri.parse("content://contacts/people");
    Cursor cursor = getContentResolver().query(uri, null, null, null, null);
  • 使用场景
    • 共享媒体文件(图片/视频)
    • 第三方应用访问系统数据
    • 实现跨进程通信

数据获取方式

网络请求(REST API)

  • 工具库:Retrofit + OkHttp + Gson(主流组合)

  • 示例代码

    // 定义接口
    public interface ApiService {
        @GET("users/{id}")
        Call<User> getUser(@Path("id") int id);
    }
    // 发起请求
    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://api.example.com")
        .addConverterFactory(GsonConverterFactory.create())
        .build();
    ApiService api = retrofit.create(ApiService.class);
    api.getUser(123).enqueue(new Callback<User>() { ... });
  • 优化策略

    • 使用Interceptor添加公共头参数
    • 配合RxJava处理异步流
    • 实现缓存机制(如OkHttp缓存)

传感器数据(硬件交互)

  • 常用传感器:加速度计、陀螺仪、光线传感器

  • 示例代码

    SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
    Sensor accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    sm.registerListener(new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent event) {
            float x = event.values[0];
            float y = event.values[1];
            float z = event.values[2];
        }
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {}
    }, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
  • 注意事项

    • 及时注销监听器(unregisterListener()
    • 处理不同设备的传感器差异

ContentProvider数据(系统级)

  • 典型场景
    • 读取通讯录:content://contacts/people
    • 访问媒体库:content://media/external/images/media
  • 示例代码
    // 获取所有图片路径
    Uri collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
    Cursor cursor = getContentResolver().query(collection, null, null, null, null);
    while (cursor.moveToNext()) {
        String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
    }
  • 权限管理
    • 需声明READ_EXTERNAL_STORAGE权限
    • Android 10+需处理分区存储(Scoped Storage)

综合应用案例

场景:电商App商品缓存

需求 解决方案
短期价格波动缓存 使用SharedPreferences存储关键字段(如价格、库存)
商品详情持久化 SQLite/Room存储完整商品信息(名称、描述、规格等)
图片资源管理 文件存储+MD5命名,配合LruCache做内存缓存
多设备同步 Firebase Realtime Database + ContentProvider实现跨设备数据同步

注意事项

  1. 权限管理
    • 外部存储需动态申请MANAGE_EXTERNAL_STORAGE权限(Android 11+)
    • 网络定位需ACCESS_COARSE_LOCATION权限
  2. 线程安全
    • Room数据库操作需在ExecutorService中执行
    • 文件IO建议使用AsyncTaskWorkManager
  3. 数据加密
    • SQLite数据库可启用SQLiteDatabase.encrypt()(Android 9+)
    • SharedPreferences使用EncryptedSharedPreferences实现AES加密
  4. 版本兼容
    • API<23设备不支持setRollbackToDeprecatedBehavior()(Room数据库回滚)
    • Android Q+需处理分区存储限制(MediaStore API重构)

相关问题与解答

Q1:如何选择数据存储方式?

A:根据以下维度判断:

  • 数据量:KB级用SharedPreferences,MB级用文件/SQLite,GB级考虑云存储
  • 结构化程度:非结构化用文件,关系型用SQLite/Room,键值对用MMKV(腾讯开源方案)
  • 访问频率:高频读写用内存缓存(如LruCache),低频用持久化存储
  • 共享需求:跨应用共享必须用ContentProvider,进程内共享优先Room/SQLite

Q2:如何处理网络数据与本地缓存的一致性?

A:采用三级缓存策略:

  1. 内存缓存:使用LruCache缓存当前屏幕数据(如Glide图片加载)
  2. 本地数据库:Room存储完整数据集,配合@Update策略更新脏数据
  3. 版本控制:为每条数据添加update_time字段,网络请求时携带最后更新时间戳,服务器返回差异数据后执行START_ACTIVITY_INTENT刷新UI
0