提问人:Drained 提问时间:11/9/2023 最后编辑:Mandar PanditDrained 更新时间:11/12/2023 访问量:32
Android Room 库。无法访问主线程上的数据库
Android Room library. Cannot access database on the main thread
问:
我有一个SQLite本地数据库,并实现了房间库。 当我完成项目时,本地数据库会创建。
尝试构建项目并得到这个:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dblearning.dbroom_test/com.dblearning.dbroom_test.RecyclerActivity}: 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.app.ActivityThread.performLaunchActivity(ActivityThread.java:3698) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3855) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:105) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:136) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2267)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7964)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:553)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
at androidx.room.RoomDatabase.assertNotMainThread(RoomDatabase.kt:439)
at androidx.room.RoomDatabase.query(RoomDatabase.kt:479)
at androidx.room.util.DBUtil.query(DBUtil.kt:75)
at com.dblearning.dbroom_test.DAO_Impl.getAll(DAO_Impl.java:165)
at com.dblearning.dbroom_test.RecyclerActivity.onCreate(RecyclerActivity.java:29)
at android.app.Activity.performCreate(Activity.java:8069)
at android.app.Activity.performCreate(Activity.java:8049)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3668)
这是我的活动类:
public class RecyclerActivity extends AppCompatActivity {
private Button add,del,update;
private EditText dataField;
List<DataEntity> dataEntityList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler);
RoomDB db = Room.databaseBuilder(this,
RoomDB.class, "tab").build();
DAO dao = db.Dao();
dataEntityList =dao.getAll();
RecyclerView recyclerView = findViewById(R.id.recyclerView);
Adapter entityAdapter = new Adapter(dataEntityList);
recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
recyclerView.setAdapter(entityAdapter);
...
}
}
这是我的 DAO 类:
@Dao
public interface DAO {
@Query("SELECT * FROM tab")
List<DataEntity> getAll();
@Query("SELECT * FROM tab WHERE id IN (:userIds)")
List<DataEntity> loadAllByIds(int[] userIds);
@Query("DELETE FROM tab")
void deleteAll();
@Query("SELECT * FROM tab WHERE first_item LIKE :first AND " + "second_item LIKE :last LIMIT 1")
DataEntity findByName(String first, String last);
@Update
void update(DataEntity entity);
@Insert
void insertAll(DataEntity... Entities);
@Delete
void delete(DataEntity Entity);
}
这是我的 Entity 类:
@Entity( tableName ="tab" )
public class DataEntity {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
public int uid;
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
@ColumnInfo(name = "first_item")
public String firstItem;
public String getFirstItem() {
return firstItem;
}
public void setFirstItem(String firstItem) {
this.firstItem = firstItem;
}
@ColumnInfo(name = "second_item")
public String secondItem;
public String getSecondItem() {
return secondItem;
}
public void setSecondItem(String secondItem) {
this.secondItem = secondItem;
}
public DataEntity(){
}
}
Excpected 通过 GUI 为将来的人口创建一个空数据库。 尝试编译我的项目时出错。 尝试谷歌解决并通过错误消息在此处搜索它,但只找到了 kotlin。
答:
1赞
Drained
11/10/2023
#1
您可以在 Codelab 中找到解决方案:developer.android.com/codelabs/android-room-with-a-view – dev.bmax
您需要在 ViewModel 中定义逻辑,该逻辑将处理 所有与数据库相关的操作,并在 IO 线程上执行。– 奇拉格·图玛尔
我添加了一个 ViewModel 和 Repository,并在我的活动中使用它。我的应用程序已构建。 CRUD 操作现在工作正常。
developer.android.com/codelabs/android-room-with-a-view 我按照这些步骤创建了一个带有存储库的 ViewModel。在添加带有 Repository 类的 ViewModel 并将其应用于我的项目之后。
评论
0赞
Szzaass
11/11/2023
如果你在自我回答中分享你所做的事情的例子,它会帮助下一个可能有同样问题的人,所以这会很好=) 此外,如果问题已解决,您可能希望将答案标记为正确,以表明此问题已解决!干得好!
上一个:Laravel 中的空属性
下一个:在颤动中不可能在列中无限滚动?
评论
ViewModel
IO