在android中使用java添加数据存储空间的问题



我试图在java中实现持久数据存储的空间。但是我遇到了一些问题。

In first try:

MyDao.java

@Dao
public interface MyDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void addUser(UserDetails userDetails);
}

MyDatabase.java

@Database(entities = {User.class}, version = 1)
public abstract class MyDatabase extends RoomDatabase {
public abstract MyDao myDao();
}

上面的应用程序崩溃错误:
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
每当我试图插入一个数据到数据库。

第二次尝试:

MyDao.java

@Dao
public interface MyDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
ListenableFuture<Integer> addUser(UserDetails userDetails);
}

MyDatabase.java

@Database(entities = {User.class}, version = 1)
public abstract class MyDatabase extends RoomDatabase {
public abstract MyDao myDao();
}

将返回类型更改为保存ListenableFuture<Integer>,因为官方文档要求这样做。应用程序不能成功构建,并显示以下错误:
error: Not sure how to handle insert method's return type.

所以,我的问题是如何正确地和成功地使用java在数据库中插入数据。
请帮忙。

你基本上是在第一次运行应用程序时创建了数据库,并试图在主线程上访问数据库,这会抛出一个错误。

当您更改数据库并尝试运行应用程序时,您更改了数据库方案,而没有提供向新版本的迁移。

对于已更改的数据库的解决方案是,打开设备管理器并删除数据库,这将强制系统使用已更新的数据库方案创建数据库的新实例。或者你可以提供一个迁移,当你更新一个已经在生产中的应用程序的数据库方案时,这是必要的

当你试图从主线程访问数据库时,解决这个错误的方法是,数据库操作需要异步处理,不允许阻塞主线程。

您需要创建一个访问数据库的线程,使用kotlin您可以简单地创建一个协程并作为协程运行操作。对于Java,你应该使用RXJava

  1. 要在UI线程中使用Room,您需要像下面这样初始化数据库

    database = Room.databaseBuilder(YOUR_CONTEXT, AppDatabase.class, "database")
    .allowMainThreadQueries() //this string need for working in UI thread
    .build();
    

但不建议在生产代码中这样做

  1. 我从未使用过Guava,但这里有一个使用ListenableFuture的指南。

正如Dominik Wuttke所说,您可以使用协程或RxJava而不是ListenableFuture进行异步工作。

在网上徘徊了很长时间后,我知道可以使用以下两种方法来编写插入查询:

  1. 使用线程类

Operations.java

public class Operations{
private MyDao myDao;
public Operations(Context context){
MyDatabase db = Room.databaseBuilder(context, MyDatabase.class, "database")
.fallbackToDestructiveMigration()
.build();
myDao = db.myDao();
}
public void insertUser(UserDetails userDetails){
new Thread{
@override
public void run(){
myDao.addUser(userDetails);
}
}.start();
}
}

MyDao.java

@Dao
public interface MyDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void addUser(UserDetails userDetails);
}

MyDatabase.java

@Database(entities = {User.class}, version = 1)
public abstract class MyDatabase extends RoomDatabase {
public abstract MyDao myDao();
}
<标题>或
  1. 使用ExecutorService类

Operations.java

public class Operations{
private MyDao myDao;
public Operations(Context context){
MyDatabase db = Room.databaseBuilder(context, MyDatabase.class, "database")
.fallbackToDestructiveMigration()
.build();
myDao = db.myDao();
}
public void insertUser(UserDetails userDetails){
MyDatabase.databaseWriteExecutor.execute(()->{
notesDb.notesDao().addNote(note));
}
}
}

MyDao.java

@Dao
public interface MyDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void addUser(UserDetails userDetails);
}

MyDatabase.java

@Database(entities = {User.class}, version = 1)
public abstract class MyDatabase extends RoomDatabase {

public static final ExecutorService databaseWriteExecutor =
Executors.newFixedThreadPool(2);
public abstract MyDao myDao();
}

最新更新