Java 房间DB始终运行if(INSTANCE==null)块,即使存在实例
my RoomDB始终跳入if(INSTANCE==null)块,即使该数据库是在第一次运行时创建的。Java 房间DB始终运行if(INSTANCE==null)块,即使存在实例,java,android,android-room,Java,Android,Android Room,my RoomDB始终跳入if(INSTANCE==null)块,即使该数据库是在第一次运行时创建的。 这是我的ShishaCounterRomDatabase.class: package com.example.shishacounter; import android.content.Context; import android.os.AsyncTask; import androidx.room.Database; import androidx.room.RoomDatabase
这是我的ShishaCounterRomDatabase.class:
package com.example.shishacounter;
import android.content.Context;
import android.os.AsyncTask;
import androidx.room.Database;
import androidx.room.RoomDatabase;
import androidx.room.Room;
import com.example.shishacounter.dao.CoalDao;
import com.example.shishacounter.dao.SmokedDao;
import com.example.shishacounter.dao.TobaccoDao;
import com.example.shishacounter.models.Coal;
import com.example.shishacounter.models.Smoked;
import com.example.shishacounter.models.Tobacco;
@Database(entities = {Tobacco.class, Coal.class, Smoked.class}, version=2, exportSchema = false)
public abstract class ShishaCounterRoomDatabase extends RoomDatabase {
public abstract TobaccoDao tobaccoDao();
int tobaccoLength;
public abstract CoalDao coalDao();
int coalLength;
public abstract SmokedDao smokedDao();
private static ShishaCounterRoomDatabase INSTANCE;
public static synchronized ShishaCounterRoomDatabase getInstance(Context context){
if(INSTANCE == null){
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
ShishaCounterRoomDatabase.class,
"db")
.build();
INSTANCE.populateInitialData();
}
return INSTANCE;
}
private void populateInitialData(){
new GetTobaccoLengthTask().execute();
new GetCoalLengthTask().execute();
if(tobaccoLength == 0){
new InsertTobaccoTask().execute();
}
if(coalLength == 0){
new InsertCoalTask().execute();
}
}
private class GetTobaccoLengthTask extends AsyncTask<Void, Void, Integer> {
@Override
protected Integer doInBackground(Void... voids) {
return INSTANCE.tobaccoDao().count();
}
@Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
tobaccoLength = integer;
}
}
private class GetCoalLengthTask extends AsyncTask<Void, Void, Integer>{
@Override
protected Integer doInBackground(Void... voids) {
return INSTANCE.coalDao().count();
}
@Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
coalLength = integer;
}
}
private class InsertTobaccoTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
for(int i=0; i<Tobacco.populateData().length; i++) {
tobaccoDao().insert(Tobacco.populateData()[i]);
}
return null;
}
}
private class InsertCoalTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
for(int i=0; i<Coal.populateData().length; i++) {
coalDao().insert(Coal.populateData()[i]);
}
return null;
}
}
}
因此,数据库显然已填充,但应用程序仍然运行if(INSTANCE==null){…}块。但我不知道为什么。当然,每次运行应用程序时,
实例
都将为null
。单音创建对象的单个实例,但不是永久的不朽对象databaseBuilder
并不意味着数据库是从头开始创建的。您的错误表明您的烟草.id
有问题。我不想复制粘贴可能的答案。以下是解决方案的变体SQLiteConstraintException:唯一约束失败:tobacco.id
表示:不要插入相同的id两次。这个问题没有任何if(INSTANCE==null)
的“块”。最有可能的是,这些任务按照您想象中的不同顺序运行……因为运行异步而从不回调;不要像那样滥用AsyncTask
。。。一次导入AsyncTask
可以在不回调的情况下工作,即使完成后应该回调。另请参阅。
2019-11-26 23:43:04.150 23774-23774/? E/e.shishacounte: Unknown bits set in runtime_flags: 0x8000
2019-11-26 23:43:04.240 23774-23805/? E/Perf: Fail to get file list com.example.shishacounter
2019-11-26 23:43:04.240 23774-23805/? E/Perf: getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array
2019-11-26 23:43:04.240 23774-23805/? E/Perf: Fail to get file list com.example.shishacounter
2019-11-26 23:43:04.240 23774-23805/? E/Perf: getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array
2019-11-26 23:43:04.388 23774-23816/? E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.example.shishacounter, PID: 23774
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$4.done(AsyncTask.java:399)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: tobacco.id (code 1555 SQLITE_CONSTRAINT_PRIMARYKEY)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:879)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:88)
at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.java:51)
at androidx.room.EntityInsertionAdapter.insert(EntityInsertionAdapter.java:80)
at com.example.shishacounter.dao.TobaccoDao_Impl.insert(TobaccoDao_Impl.java:72)
at com.example.shishacounter.ShishaCounterRoomDatabase$InsertTobaccoTask.doInBackground(ShishaCounterRoomDatabase.java:89)
at com.example.shishacounter.ShishaCounterRoomDatabase$InsertTobaccoTask.doInBackground(ShishaCounterRoomDatabase.java:84)
at android.os.AsyncTask$3.call(AsyncTask.java:378)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)