javaandroidandroid-sqliteandroid-roomcrud

Android Room library. Cannot access database on the main thread


I have a SQLite local database with implemented Room library. Local database creates when i complilate project.

Tried to build project and got this:

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)

Here is my Activity class:

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);
           ... 
    }
}

Here is my DAO class:

@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);
}

And here is my Entity class:

@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 to create an empty database for future population by GUI. Got an error while trying to compilate my project. Tryied to google solvation and search it here by error message, but found only for kotlin.


Solution

  • You can find the solution in the codelab: developer.android.com/codelabs/android-room-with-a-view – dev.bmax

    You need to define your logic inside the ViewModel which will handle all you operation related to DB and also performs that on IO Thread. – Chirag Thummar

    I added a ViewModel and Repository and use it in my activity. My app was built. And CRUD operations now is working correctly.

    developer.android.com/codelabs/android-room-with-a-view i was followed these steps and created a ViewModel with Repository. After adding ViewModel with Repository classes and adapting that for my project.