在 Android 中,数据存储是一个关键的方面,因为它涉及到应用程序如何管理和持久化数据。以下是 Android 中常见的数据存储方式和介绍:
-
Shared Preferences(共享首选项) :
- 用于存储小型键值对数据,通常用于保存用户首选项、配置信息和应用程序设置等。数据以 XML 文件的形式存储在应用的私有目录中,只能被应用本身访问。
-
Internal Storage(内部存储) :
- 内部存储用于在应用的私有目录中存储文件。这些文件对于应用程序来说是私有的,其他应用程序无法直接访问。内部存储适用于存储应用程序的数据库文件、缓存文件等。
-
External Storage(外部存储) :
- 外部存储用于在外部存储设备(如 SD 卡)上存储文件。这些文件可以被其他应用程序或用户访问,但需要相应的权限。外部存储适用于存储大型媒体文件、下载文件等。
-
SQLite Database(SQLite 数据库) :
- SQLite 是一个轻量级的嵌入式关系型数据库引擎,适用于存储结构化数据。它是 Android 平台的默认数据库引擎,用于创建和管理应用程序的本地数据库。
-
Content Providers(内容提供者) :
- 内容提供者是一种用于跨应用程序共享数据的机制。它通常用于让应用程序之间共享数据,例如联系人数据、日历事件等。内容提供者还提供了一种标准化的访问方式,允许其他应用程序访问您的应用程序中的数据。
-
Network Storage(网络存储) :
- 您可以使用网络连接将数据存储在云端服务器上,例如使用云存储服务(如 Firebase、Amazon S3)或通过 Web API 与服务器进行交互。这使得数据可以在多台设备之间同步,并支持远程访问。
-
Room Persistence Library(Room 持久性库) :
- Room 是 Android 的数据库持久性库,它结合了 SQLite 数据库和 LiveData,用于处理应用程序的本地数据存储需求。它提供了更方便的数据库访问方式。
-
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