java - "Cannot access database on the main thread"AsyncTask异常

标签 java android android-room android-livedata

我用 LiveData 构建了一个简单的 Room 示例,但是得到了一个

Cannot access database on the main thread"- IllegalStateException

我的一般架构是带有 fragment 的 Activity , fragment 具有带有 Room 的 ViewModel 和 Repository。

我的调用从这里开始(我剪掉了 fragment ,点击调用该方法的按钮)。

我使用的是androidannotations,但应该与错误无关。

在我看来,它很直接,插入调用显然是在 AsyncTask 中,所以这就是为什么我真的对异常感到困惑的原因。

我的 View 模型:

class FragmentAddKeywordsViewModel extends AndroidViewModel {
KeywordsRepository repository;

public FragmentAddKeywordsViewModel(@NonNull Application application) {
    super(application);
    if (repository == null) {
        repository = new KeywordRepository(application);
    }
}

public void addKeyword(Keyword keyword) {
        repository.addKeyword(keyword);
}

}

这是我的仓库:

public class KeywordsRepository {
private KeywordDao keywordDao;

public KeywordsRepository (Application application) {
    KeywordDatabase db = KeywordDatabase.getDatabase(application);
    keywordDao= db.keywordDao();

}

public void addKeyword(Keyword keyword) {
    new insertAsyncTask(keywordDao).doInBackground(keyword);
}


private static class insertAsyncTask extends AsyncTask<Keyword, Void, Void> {
    private KeywordDao mAsyncTaskDao;

    insertAsyncTask(KeywordDao dao) {
        mAsyncTaskDao = dao;
    }

    @Override
    protected Void doInBackground(final Keyword... params) {
        mAsyncTaskDao.insert(params[0]); // This line throws the exception
        Log.d(getClass().getSimpleName(), "do in background 1");
        return null;
    }
}
}

我的数据库

@Database(entities = {Keywords.class}, version = 1, exportSchema = false)
public abstract class KeywordDatabase extends RoomDatabase {

public abstract KeywordsDao keywordDao();

private static KeywordDatabase INSTANCE;

private static RoomDatabase.Callback sRoomDatabaseCallback =
        new RoomDatabase.Callback() {
            @Override
            public void onOpen(@NonNull SupportSQLiteDatabase db) {
                super.onOpen(db);
            }
        };

public static KeywordDatabase getDatabase(final Context context) {
    if (INSTANCE == null) {
        synchronized (KeywordDatabase .class) {
            if (INSTANCE == null) {
                INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                        KeywordDatabase.class, "keywords")
                        .addCallback(sRoomDatabaseCallback)
                        .build();
            }
        }
    }
    return INSTANCE;

}
}

最后但同样重要的是我的道

@Dao
interface KeywordDao {
@Query("SELECT * FROM keywords")
LiveData<List<Keyword>> getAllKeywords();


@Insert
void insert(Keyword keyword);

@Delete
void delete(Keyword keyword);

@Query("DELETE FROM keywords")
void deleteAll();
}

这就是我的错误堆栈的结尾:

java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time. at android.arch.persistence.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:164) at android.arch.persistence.room.RoomDatabase.beginTransaction(RoomDatabase.java:211) at org.name.project.package.KeywordDao_Impl.insert(KeywordDao_Impl.java:81) at org.name.project.package.KeywordsRepository$insertAsyncTask.doInBackground(KeywordsRepository.java:42)

最佳答案

你需要调用execute让asychtask的doInBackground方法在后台运行

new insertAsyncTask(keywordDao).execute(keyword);

否则用这个

new insertAsyncTask(keywordDao).doInBackground(keyword);

您只是在调用类实例的方法。

类似的例子是 java 中的 Thread,其中 threadInstance.start() 创建的线程不是 threadInstance.run()

关于java - "Cannot access database on the main thread"AsyncTask异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49780040/

相关文章:

java - 离线使用maven

android - 在 Android 3.1 上实现 onShowCustomView 在 HTML5VideoFullScreen 中抛出异常

Android webview onReceivedError() 不工作

android - Stacked Wear 通知也显示在手机上

java - 房间数据库 : RecyclerView does not update after delete data in detail activity

android - 即使添加 androidx.room:room-ktx 后,房间错误 : Type of the parameter must be a class annotated with @Entity or a collection/array of it.

java - KafkaProducer 未生成> 1 MB 的消息到主题

java - 通知其他 Activity 偏好已更改

java - 在派生类构造函数(或工厂)中初始化基类的模式

android - 任务之间的 Gradle 依赖关系