安卓数据存储

105 阅读5分钟

在 Android 中,数据存储是一个关键的方面,因为它涉及到应用程序如何管理和持久化数据。以下是 Android 中常见的数据存储方式和介绍:

  1. Shared Preferences(共享首选项) :

    • 用于存储小型键值对数据,通常用于保存用户首选项、配置信息和应用程序设置等。数据以 XML 文件的形式存储在应用的私有目录中,只能被应用本身访问。
  2. Internal Storage(内部存储) :

    • 内部存储用于在应用的私有目录中存储文件。这些文件对于应用程序来说是私有的,其他应用程序无法直接访问。内部存储适用于存储应用程序的数据库文件、缓存文件等。
  3. External Storage(外部存储) :

    • 外部存储用于在外部存储设备(如 SD 卡)上存储文件。这些文件可以被其他应用程序或用户访问,但需要相应的权限。外部存储适用于存储大型媒体文件、下载文件等。
  4. SQLite Database(SQLite 数据库) :

    • SQLite 是一个轻量级的嵌入式关系型数据库引擎,适用于存储结构化数据。它是 Android 平台的默认数据库引擎,用于创建和管理应用程序的本地数据库。
  5. Content Providers(内容提供者) :

    • 内容提供者是一种用于跨应用程序共享数据的机制。它通常用于让应用程序之间共享数据,例如联系人数据、日历事件等。内容提供者还提供了一种标准化的访问方式,允许其他应用程序访问您的应用程序中的数据。
  6. Network Storage(网络存储) :

    • 您可以使用网络连接将数据存储在云端服务器上,例如使用云存储服务(如 Firebase、Amazon S3)或通过 Web API 与服务器进行交互。这使得数据可以在多台设备之间同步,并支持远程访问。
  7. Room Persistence Library(Room 持久性库) :

    • Room 是 Android 的数据库持久性库,它结合了 SQLite 数据库和 LiveData,用于处理应用程序的本地数据存储需求。它提供了更方便的数据库访问方式。
  8. File Storage(文件存储) :

    • 您可以使用标准的文件读写操作来存储和管理应用程序的数据文件,包括内部存储和外部存储。这适用于存储应用程序的配置文件、日志文件等。

代码示例:

**线程安全性**: SharedPreferences 不是线程安全的。如果多个线程同时尝试修改 SharedPreferences,可能会导致数据不一致性。因此,建议在主线程上执行读写操作。

// 获取 SharedPreferences 对象
//我们创建了一个名为 "my_preferences" 的 SharedPreferences 文件。第二个参数 `MODE_PRIVATE` 表示这个文件是私有的,只能被应用程序本身访问。
SharedPreferences sharedPreferences = getSharedPreferences("my_preferences", MODE_PRIVATE);

// 获取 SharedPreferences.Editor 对象
SharedPreferences.Editor editor = sharedPreferences.edit();

// 写入数据
editor.putString("username", "john_doe");
editor.putInt("score", 1000);

// 提交更改
editor.apply();

// 读取数据
String username = sharedPreferences.getString("username", "default_username");
int score = sharedPreferences.getInt("score", 0);

// 使用读取的数据
Log.d("SharedPreferences", "Username: " + username);
Log.d("SharedPreferences", "Score: " + score);

// 修改数据
editor.putString("username", "new_username");
editor.putInt("score", 1500);

// 删除数据
editor.remove("key_to_remove");


内部存储代码示例:

1、先注册权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
2、activity代码
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    private Button writeButton;
    private Button readButton;

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

        writeButton = findViewById(R.id.writeButton);
        readButton = findViewById(R.id.readButton);

        writeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                writeToFile();
            }
        });

        readButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                readFromFile();
            }
        });
    }

    private void writeToFile() {
        String filename = "sample.txt";
        String content = "This is the content to write to the file.";

        try {
            // 获取内部存储目录
            File internalStorageDir = getFilesDir();

            // 创建文件对象
            File file = new File(internalStorageDir, filename);

            // 打开文件输出流
            FileOutputStream fos = new FileOutputStream(file);

            // 将内容写入文件
            fos.write(content.getBytes());

            // 关闭文件输出流
            fos.close();

            // 显示成功消息
            showToast("File saved to internal storage.");
        } catch (IOException e) {
            e.printStackTrace();
            showToast("Error writing to file.");
        }
    }

    private void readFromFile() {
        String filename = "sample.txt";

        try {
            // 获取内部存储目录
            File internalStorageDir = getFilesDir();

            // 创建文件对象
            File file = new File(internalStorageDir, filename);

            // 打开文件输入流
            FileInputStream fis = new FileInputStream(file);

            // 读取文件内容
            int length;
            byte[] buffer = new byte[1024];
            StringBuilder content = new StringBuilder();
            while ((length = fis.read(buffer)) != -1) {
                content.append(new String(buffer, 0, length));
            }

            // 关闭文件输入流
            fis.close();

            // 显示读取的内容
            showToast("File content: " + content.toString());
        } catch (IOException e) {
            e.printStackTrace();
            showToast("Error reading from file.");
        }
    }

    private void showToast(String message) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }
}

外部存储代码示例:

import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    private Button writeButton;
    private Button readButton;

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

        writeButton = findViewById(R.id.writeButton);
        readButton = findViewById(R.id.readButton);

        writeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                writeToFile();
            }
        });

        readButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                readFromFile();
            }
        });
    }

    private void writeToFile() {
        String filename = "sample_external.txt";
        String content = "This is the content to write to the file on external storage.";

        try {
            // 检查外部存储是否可用
            if (isExternalStorageWritable()) {
                // 获取外部存储目录
                File externalStorageDir = Environment.getExternalStorageDirectory();

                // 创建文件对象
                File file = new File(externalStorageDir, filename);

                // 打开文件输出流
                FileOutputStream fos = new FileOutputStream(file);

                // 将内容写入文件
                fos.write(content.getBytes());

                // 关闭文件输出流
                fos.close();

                // 显示成功消息
                showToast("File saved to external storage.");
            } else {
                showToast("External storage is not available.");
            }
        } catch (IOException e) {
            e.printStackTrace();
            showToast("Error writing to file.");
        }
    }

    private void readFromFile() {
        String filename = "sample_external.txt";

        try {
            // 检查外部存储是否可用
            if (isExternalStorageReadable()) {
                // 获取外部存储目录
                File externalStorageDir = Environment.getExternalStorageDirectory();

                // 创建文件对象
                File file = new File(externalStorageDir, filename);

                // 打开文件输入流
                FileInputStream fis = new FileInputStream(file);

                // 读取文件内容
                int length;
                byte[] buffer = new byte[1024];
                StringBuilder content = new StringBuilder();
                while ((length = fis.read(buffer)) != -1) {
                    content.append(new String(buffer, 0, length));
                }

                // 关闭文件输入流
                fis.close();

                // 显示读取的内容
                showToast("File content: " + content.toString());
            } else {
                showToast("External storage is not available.");
            }
        } catch (IOException e) {
            e.printStackTrace();
            showToast("Error reading from file.");
        }
    }

    private void showToast(String message) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }

    private boolean isExternalStorageWritable() {
        String state = Environment.getExternalStorageState();
        return Environment.MEDIA_MOUNTED.equals(state);
    }

    private boolean isExternalStorageReadable() {
        String state = Environment.getExternalStorageState();
        return Environment.MEDIA_MOUNTED.equals(state) ||
                Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
    }
}

Room代码示例:

1、首先,在您的 Android 项目中的 `build.gradle` 文件中添加 Room 的依赖:
dependencies {
    // 添加 Room 依赖
    implementation "androidx.room:room-runtime:2.4.0"
    annotationProcessor "androidx.room:room-compiler:2.4.0"
}
2、创建实体类
@Entity(tableName = "users")
public class User {
    @PrimaryKey(autoGenerate = true)
    public long id;
    
    @ColumnInfo(name = "first_name")
    public String firstName;
    
    @ColumnInfo(name = "last_name")
    public String lastName;
}
3、创建 DAO(Data Access Object)接口
@Dao
public interface UserDao {
    @Insert
    void insert(User user);
    
    @Query("SELECT * FROM users WHERE id = :userId")
    User getUserById(long userId);
    
    @Update
    void updateUser(User user);
    
    @Delete
    void deleteUser(User user);
}
4. 创建数据库:使用 `@Database` 注解标记抽象类,并在类中定义数据库的版本号和实体类。示例:
   @Database(entities = {User.class}, version = 1)
   public abstract class MyAppDatabase extends RoomDatabase {
        public abstract UserDao userDao();
   }
   
5. 初始化 Room 数据库
public class MyApp extends Application {
    private static MyAppDatabase database;

    @Override
    public void onCreate() {
        super.onCreate();

        // 初始化数据库实例
        database = Room.databaseBuilder(getApplicationContext(), MyAppDatabase.class, "myapp-database")
            .allowMainThreadQueries() // 在主线程上执行查询(仅用于演示,不建议在生产中使用)
            .build();
    }

    public static MyAppDatabase getDatabase() {
        return database;
    }
}

6.执行数据库操作
MyAppDatabase db = MyApp.getDatabase();

// 插入用户
User user = new User();
user.firstName = "John";
user.lastName = "Doe";
db.userDao().insert(user);

// 查询用户
User retrievedUser = db.userDao().getUserById(1);

// 更新用户
retrievedUser.firstName = "Jane";
db.userDao().updateUser(retrievedUser);

// 删除用户
db.userDao().deleteUser(retrievedUser);

后面再补充内容提供者 和 Sqlite