第五章《Android 数据存储》

第五章 Android 数据存储详解(文件、SharedPreferences、SQLite)

本章目标:

  • 理解 Android 四种数据存储方式

  • 掌握文件存储与 SharedPreferences 的基本操作

  • 掌握 SQLite 数据库的创建与 CRUD 操作

  • 完成两个实战演练:

    ✅ 保存 QQ 账号与密码

    ✅ 模拟"绿豆通讯录"数据库应用


🧭 目录


一、Android 数据存储方式概览

存储方式 特点 适用场景
文件存储 读写简单文本 轻量数据保存
SharedPreferences 存取键值对(XML) 保存设置、登录信息
SQLite 结构化关系型数据库 本地持久化大量数据
网络存储 与服务器交互 云端同步数据

二、文件存储(File Storage)

1️⃣ 写入数据到文件

复制代码
public void saveToFile(String account, String password) {
    try {
        FileOutputStream fos = openFileOutput("qq_data.txt", MODE_PRIVATE);
        String content = account + "," + password;
        fos.write(content.getBytes());
        fos.close();
        Toast.makeText(this, "保存成功!", Toast.LENGTH_SHORT).show();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

📂 保存路径:/data/data/<包名>/files/qq_data.txt


2️⃣ 从文件读取数据

复制代码
public String readFromFile() {
    try {
        FileInputStream fis = openFileInput("qq_data.txt");
        BufferedReader br = new BufferedReader(new InputStreamReader(fis));
        return br.readLine();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return "";
}

3️⃣ 实战:保存 QQ 账号与密码(文件版)

布局文件:activity_main.xml

复制代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:padding="20dp"
    android:gravity="center">

    <EditText
        android:id="@+id/et_account"
        android:hint="QQ账号"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <EditText
        android:id="@+id/et_password"
        android:hint="密码"
        android:inputType="textPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/btn_save"
        android:text="保存到文件"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

Java:MainActivity.java

复制代码
btn_save.setOnClickListener(v -> {
    String account = et_account.getText().toString();
    String password = et_password.getText().toString();
    saveToFile(account, password);
});

三、SharedPreferences 存储

1️⃣ 写入与读取数据

保存数据:

复制代码
SharedPreferences sp = getSharedPreferences("qq_prefs", MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString("account", "123456");
editor.putString("password", "abc123");
editor.apply();  // 异步提交

读取数据:

复制代码
SharedPreferences sp = getSharedPreferences("qq_prefs", MODE_PRIVATE);
String account = sp.getString("account", "");
String password = sp.getString("password", "");

2️⃣ 实战:保存 QQ 账号与密码(SP版)

复制代码
btn_save.setOnClickListener(v -> {
    SharedPreferences.Editor editor =
        getSharedPreferences("qq_info", MODE_PRIVATE).edit();
    editor.putString("account", et_account.getText().toString());
    editor.putString("password", et_password.getText().toString());
    editor.apply();
    Toast.makeText(this, "保存成功!", Toast.LENGTH_SHORT).show();
});

btn_load.setOnClickListener(v -> {
    SharedPreferences sp = getSharedPreferences("qq_info", MODE_PRIVATE);
    et_account.setText(sp.getString("account", ""));
    et_password.setText(sp.getString("password", ""));
});

🗂 数据保存路径:/data/data/<包名>/shared_prefs/qq_info.xml


四、SQLite 数据库存储

1️⃣ 创建数据库与表

复制代码
public class MyDBHelper extends SQLiteOpenHelper {

    public MyDBHelper(Context context) {
        super(context, "contact.db", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE contact (" +
                "id INTEGER PRIMARY KEY AUTOINCREMENT, " +
                "name TEXT, " +
                "phone TEXT)");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldV, int newV) {
        db.execSQL("DROP TABLE IF EXISTS contact");
        onCreate(db);
    }
}

2️⃣ 数据库的增删改查(CRUD)

复制代码
SQLiteDatabase db = helper.getWritableDatabase();

// 插入
ContentValues values = new ContentValues();
values.put("name", "小明");
values.put("phone", "10086");
db.insert("contact", null, values);

// 查询
Cursor cursor = db.query("contact", null, null, null, null, null, null);
while (cursor.moveToNext()) {
    String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));
    String phone = cursor.getString(cursor.getColumnIndexOrThrow("phone"));
    Log.d("Contact", name + ":" + phone);
}

// 更新
ContentValues cv = new ContentValues();
cv.put("phone", "10010");
db.update("contact", cv, "name=?", new String[]{"小明"});

// 删除
db.delete("contact", "name=?", new String[]{"小明"});

3️⃣ 数据库事务操作

复制代码
db.beginTransaction();
try {
    db.execSQL("UPDATE contact SET phone='123456' WHERE name='小红'");
    db.setTransactionSuccessful();
} finally {
    db.endTransaction();
}

4️⃣ 实战:绿豆通讯录(SQLite)

布局(简版)
复制代码
<LinearLayout
    android:orientation="vertical"
    android:padding="16dp">

    <EditText
        android:id="@+id/et_name"
        android:hint="联系人姓名"/>

    <EditText
        android:id="@+id/et_phone"
        android:hint="电话号码"/>

    <Button
        android:id="@+id/btn_add"
        android:text="添加联系人"/>

    <ListView
        android:id="@+id/list_contact"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>
Java 逻辑
复制代码
MyDBHelper helper = new MyDBHelper(this);
SQLiteDatabase db = helper.getWritableDatabase();

btn_add.setOnClickListener(v -> {
    ContentValues values = new ContentValues();
    values.put("name", et_name.getText().toString());
    values.put("phone", et_phone.getText().toString());
    db.insert("contact", null, values);
    Toast.makeText(this, "添加成功", Toast.LENGTH_SHORT).show();
    loadContacts();
});

private void loadContacts() {
    List<String> data = new ArrayList<>();
    Cursor cursor = db.query("contact", null, null, null, null, null, null);
    while (cursor.moveToNext()) {
        String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));
        String phone = cursor.getString(cursor.getColumnIndexOrThrow("phone"));
        data.add(name + " : " + phone);
    }
    list_contact.setAdapter(new ArrayAdapter<>(this,
        android.R.layout.simple_list_item_1, data));
}

🎯 效果:

可输入姓名和电话,点击"添加联系人"即保存至数据库中,并实时显示在列表中。


五、总结与对比

存储方式 数据格式 特点 示例场景
文件存储 文本/二进制 简单易用 账号密码保存
SharedPreferences 键值对(XML) 轻量级,自动管理 登录信息、设置
SQLite 表结构(数据库) 强大查询能力 通讯录、订单表
网络存储 JSON/REST API 云端同步 聊天记录、用户资料

学习建议:

  • 熟练掌握 SharedPreferencesSQLite 的使用。

  • 实战项目中常组合使用两种存储方式(例如:登录信息用 SP,数据用 DB)。

  • 下章建议学习内容提供器 ContentProvider 与系统共享数据机制。


相关推荐
煎蛋学姐几秒前
SSM社区生鲜电商平台dq96z(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·用户管理·ssm 框架·社区生鲜电商·商品信息管理
杨云龙UP2 分钟前
从0搭建Oracle ODA NFS异地备份:从YUM源到RMAN定时任务的全流程
linux·运维·数据库·oracle
倔强的石头_9 分钟前
从 Oracle 到 KingbaseES:破解迁移痛点,解锁信创时代数据库新可能
数据库
踢足球092922 分钟前
Redis的典型应用
数据库·redis·缓存
hadage23337 分钟前
--- redis 常见问题 ---
数据库·redis·mybatis
O***P5711 小时前
redis批量删除namespace下的数据
数据库·redis·缓存
5***26221 小时前
SQL Server导出和导入可选的数据库表和数据,以sql脚本形式
数据库·sql
JSUITDLWXL1 小时前
Oracle记录被锁的查询与强制删除方法
数据库·oracle
雨中飘荡的记忆2 小时前
SpringAI_Redis向量库实战
数据库·redis·缓存
姓蔡小朋友2 小时前
Redis网络I/O模型
网络·数据库·redis