上一篇
安卓开发数据获取和存储方法
- 行业动态
- 2025-04-22
- 1
数据存储方式
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操作) |
| 数据格式 | 需自行处理序列化/反序列化 |
| 适用场景 | 配置文件保存、日志记录 |
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 = 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实现跨设备数据同步 |
注意事项
- 权限管理:
- 外部存储需动态申请
MANAGE_EXTERNAL_STORAGE
权限(Android 11+) - 网络定位需
ACCESS_COARSE_LOCATION
权限
- 外部存储需动态申请
- 线程安全:
- Room数据库操作需在ExecutorService中执行
- 文件IO建议使用
AsyncTask
或WorkManager
- 数据加密:
- SQLite数据库可启用
SQLiteDatabase.encrypt()
(Android 9+) - SharedPreferences使用
EncryptedSharedPreferences
实现AES加密
- SQLite数据库可启用
- 版本兼容:
- API<23设备不支持
setRollbackToDeprecatedBehavior()
(Room数据库回滚) - Android Q+需处理分区存储限制(
MediaStore
API重构)
- API<23设备不支持
相关问题与解答
Q1:如何选择数据存储方式?
A:根据以下维度判断:
- 数据量:KB级用SharedPreferences,MB级用文件/SQLite,GB级考虑云存储
- 结构化程度:非结构化用文件,关系型用SQLite/Room,键值对用MMKV(腾讯开源方案)
- 访问频率:高频读写用内存缓存(如LruCache),低频用持久化存储
- 共享需求:跨应用共享必须用ContentProvider,进程内共享优先Room/SQLite
Q2:如何处理网络数据与本地缓存的一致性?
A:采用三级缓存策略:
- 内存缓存:使用
LruCache
缓存当前屏幕数据(如Glide图片加载) - 本地数据库:Room存储完整数据集,配合
@Update
策略更新脏数据 - 版本控制:为每条数据添加
update_time
字段,网络请求时携带最后更新时间戳,服务器返回差异数据后执行START_ACTIVITY_INTENT
刷新UI