序言
因此,对于android开发来说我是一个新手,目前正在开发一个应用程序,该应用程序从REST服务器中检索数据作为JSON响应。该应用程序需要脱机运行,因此,为了实现此目的,基于android的建议,我决定使用Room Database,并遵循此教程:Room with View tutorial。
本教程本身做得很好,我能够按照基本设置进行调整,并根据自己的需要进行调整。
问题
但是,使用来自服务器的数据预填充RoomDatabase时遇到了一些麻烦。本教程通过使用静态数据说明了预填充方面,并且工作正常。但是,当我尝试修改该数据以使用通过Volley请求从服务器获取的数据时,却遇到了问题。
代码
当我尝试运行以下内容
public abstract class AppDatabase extends RoomDatabase {
public abstract MachineMovementDao machineMovementDao();
private static volatile AppDatabase INSTANCE;
private static Context ctx;
public static AppDatabase getDatabase(final Context context) {
ctx = context;
if (INSTANCE == null) {
synchronized (AppDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
AppDatabase.class, "local_database")
.addCallback(sRoomDatabaseCallback)
//.fallbackToDestructiveMigration()
.build();
}
}
}
return INSTANCE;
}
public static RoomDatabase.Callback sRoomDatabaseCallback =
new RoomDatabase.Callback() {
@Override
public void onOpen(@NonNull SupportSQLiteDatabase db) {
super.onOpen(db);
new PopulateDbAsync(INSTANCE).execute();
}
};
private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> {
private final MachineMovementDao machineMovementDao;
PopulateDbAsync(AppDatabase db) {
machineMovementDao = db.machineMovementDao();
}
@Override
protected Void doInBackground(final Void... params) {
machineMovementDao.deleteAll();
String url = "http://192.168.10.124:8888/movement/machine/all";
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest
(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
try {
for (int i = 0; i < response.length(); i++) {
JSONObject jsonObject = response.getJSONObject(i);
MachineMovement movement = new MachineMovement(jsonObject);
machineMovementDao.insert(movement);
}
} catch (JSONException e) {
System.out.println(e.toString());
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
System.out.println(">>>>>>>>>>>>>>>>>>> > Error:" + volleyError.toString());
}
});
DataVolleyRequest.getInstance(ctx.getApplicationContext())
.addToRequestQueue(jsonArrayRequest);
/*
MachineMovement movement = new MachineMovement("AMUSEMENT_MACHINE", "00003",
"SN969NI7VCSXN", 1);
movement.setLocationFromID(1);
movement.setLocationToID(2);
machineMovementDao.insert(movement);
movement = new MachineMovement("AMUSEMENT_MACHINE", "00003",
"SN969NI7VCSXN", 1);
movement.setLocationFromID(2);
movement.setLocationToID(1);
machineMovementDao.insert(movement);
*/
return null;
}
}
}
错误
我收到以下错误
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.sunnygroup.backoffice.tdcapp, PID: 18175
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:204)
at android.arch.persistence.room.RoomDatabase.beginTransaction(RoomDatabase.java:251)
at com.sunnygroup.backoffice.tdcapp.daos.MachineMovementDao_Impl.insert(MachineMovementDao_Impl.java:115)
at com.sunnygroup.backoffice.tdcapp.database.AppDatabase$PopulateDbAsync$1.onResponse(AppDatabase.java:78)
at com.sunnygroup.backoffice.tdcapp.database.AppDatabase$PopulateDbAsync$1.onResponse(AppDatabase.java:71)
at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:90)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5593)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
第78行是您在我的代码中看到的行
machineMovementDao.insert(movement);
任何帮助将不胜感激
答案 0 :(得分:0)
您可以留出空间在主线程(https://developer.android.com/reference/androidx/room/RoomDatabase.Builder.html#allowMainThreadQueries())上运行
在您的情况下:
AppDatabase.class, "local_database")
.addCallback(sRoomDatabaseCallback)
.allowMainThreadQueries()
.build();
注意,在生产应用中不建议这样做。
或者您可以在后台线程上运行它。您可以在asyncTask上运行该指令,也可以考虑将RxJava集成到Room实现中。 Here是一个例子。