E/SQLiteLog: (283) 从 WAL 文件恢复帧
E/SQLiteLog: (283) recovered frames from WAL file
我每次启动我的应用程序时都会出错。
E/SQLiteLog: (283) recovered 22 frames from WAL file /data/data/com.dmitrysimakov.kilogram/databases/androidx.work.workdb-wal
应用程序运行良好,但我想知道为什么会出现此错误。 databases/androidx.work.workdb-wal 是个工人日记。我使用 Worker 预填充我的数据库。
Room.databaseBuilder(app, KilogramDb::class.java, "kilogram.db")
.addCallback(object : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
val request = OneTimeWorkRequestBuilder<SeedDatabaseWorker>().build()
WorkManager.getInstance().enqueue(request)
}
})
.fallbackToDestructiveMigration()
.build()
此消息表示数据库在退出前未关闭,因此 WAL 文件未正确清理。
因此,当应用程序启动时,它意识到它需要清理 WAL 文件,然后这样做,但发出错误,因为它可能表明存在严重问题。
要解决此问题,您需要在完成后关闭数据库。
您可能会对此感兴趣(Richard Hipp 是 SQLite 的主要负责人,如果您还不知道的话) Continuous recovery of journal
我正在使用绑定服务连接到房间数据库,所以我在我的 RoomService.onDestroy()
方法中使用此代码:
@Override
public final void
onDestroy()
{
super
.onDestroy();
if(roomDatabase != null)
{
if(roomDatabase
.isOpen())
{
roomDatabase
.close();
}
}
}
如果您在 Application
单例或 Activity
中创建 RoomDatabase 实例,您可以在那里做同样的事情(在相应的 onDestroy()
方法中)。
为方便起见,这里是我在 MainActivity
class 中用于关闭绑定服务中的数据库的代码:
@Override
protected final void
onDestroy()
{
super.onDestroy();
if(isFinishing())
{
if(mainViewModel != null)
{
mainViewModel
.onDestroy();
}
}
}
在 MainViewModel.onDestroy()
中,我向绑定服务发送消息以关闭 roomDatabase
,然后解除绑定 roomService
:
public final void
onDestroy()
{
if(contextWeakReference != null)
{
final Context
context =
contextWeakReference
.get();
if(context != null)
{
if(roomServiceConnection != null)
{
if(boundToRoomService)
{
sendDBCloseMessageToRoomService();
context
.unbindService
(roomServiceConnection);
}
}
}
}
}
private void
sendDBCloseMessageToRoomService()
{
try
{
final Message message =
Message.obtain
(null, MSG_DB_CLOSE);
if(message != null)
{
if(messengerToRoomService != null)
{
messengerToRoomService
.send(message);
}
}
}
catch(final RemoteException e)
{
e.printStackTrace();
}
}
在 RoomService
中,我收到要关闭的消息 roomDatabase
:
public class RoomService
extends Service
{
@NonNull @NonNls public static final
String DATABASE_NAME = "room_database";
public static final int MSG_DB_CLOSE = 108;
@Nullable public RoomDatabase roomDatabase;
private final IBinder roomBinder = new Binder();
private WeakReference<Context> contextWeakReference;
@Nullable public Messenger messengerFromRoomService;
@Nullable public Messenger messengerToRoomService;
private static class RoomServiceHandler
extends Handler
{
@Nullable private final
WeakReference<RoomService> roomServiceWeakReference;
RoomServiceHandler
(@Nullable final
RoomService service)
{
if(service != null)
{
roomServiceWeakReference =
new WeakReference<RoomService>
(service);
}
else
{
roomServiceWeakReference = null;
}
}
@Override
public final void
handleMessage
(@Nullable final
Message message)
{
if(message != null)
{
final int what =
message.what;
switch(what)
{
case MSG_DB_CLOSE:
{
handleDBCloseMessage
(message);
break;
}
}
}
}
private void
handleDBCloseMessage
(@Nullable final
Message message)
{
if(message != null)
{
final RoomService
service =
roomServiceWeakReference
.get();
if(service != null)
{
if(service
.roomDatabase != null)
{
if(service
.roomDatabase
.isOpen())
{
service
.roomDatabase
.close();
}
}
}
}
}
}
@Override
public final void
onCreate()
{
super.onCreate();
// initialize application context weak reference
final Context
applicationContext =
getApplicationContext();
if(applicationContext != null)
{
contextWeakReference =
new WeakReference<Context>
(applicationContext);
// initialize database
roomDatabase =
Room
.databaseBuilder
(applicationContext,
MyRoomDatabase.class,
DATABASE_NAME)
.build();
if(roomDatabase != null)
{
// initialise your DAO here
yourDao =
roomDatabase
.yourDao();
}
}
final RoomServiceHandler
roomServiceHandler =
new RoomServiceHandler(this);
if(roomServiceHandler != null)
{
messengerToRoomService =
new Messenger(roomServiceHandler);
}
}
@Nullable
@Override
public final IBinder
onBind
(@Nullable final
Intent intent)
{
IBinder result = null;
if(messengerToRoomService != null)
{
final IBinder
roomBinder =
messengerToRoomService
.getBinder();
if(roomBinder != null)
{
result = roomBinder;
}
}
return result;
}
}
我每次启动我的应用程序时都会出错。
E/SQLiteLog: (283) recovered 22 frames from WAL file /data/data/com.dmitrysimakov.kilogram/databases/androidx.work.workdb-wal
应用程序运行良好,但我想知道为什么会出现此错误。 databases/androidx.work.workdb-wal 是个工人日记。我使用 Worker 预填充我的数据库。
Room.databaseBuilder(app, KilogramDb::class.java, "kilogram.db")
.addCallback(object : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
val request = OneTimeWorkRequestBuilder<SeedDatabaseWorker>().build()
WorkManager.getInstance().enqueue(request)
}
})
.fallbackToDestructiveMigration()
.build()
此消息表示数据库在退出前未关闭,因此 WAL 文件未正确清理。
因此,当应用程序启动时,它意识到它需要清理 WAL 文件,然后这样做,但发出错误,因为它可能表明存在严重问题。
要解决此问题,您需要在完成后关闭数据库。
您可能会对此感兴趣(Richard Hipp 是 SQLite 的主要负责人,如果您还不知道的话) Continuous recovery of journal
我正在使用绑定服务连接到房间数据库,所以我在我的 RoomService.onDestroy()
方法中使用此代码:
@Override
public final void
onDestroy()
{
super
.onDestroy();
if(roomDatabase != null)
{
if(roomDatabase
.isOpen())
{
roomDatabase
.close();
}
}
}
如果您在 Application
单例或 Activity
中创建 RoomDatabase 实例,您可以在那里做同样的事情(在相应的 onDestroy()
方法中)。
为方便起见,这里是我在 MainActivity
class 中用于关闭绑定服务中的数据库的代码:
@Override
protected final void
onDestroy()
{
super.onDestroy();
if(isFinishing())
{
if(mainViewModel != null)
{
mainViewModel
.onDestroy();
}
}
}
在 MainViewModel.onDestroy()
中,我向绑定服务发送消息以关闭 roomDatabase
,然后解除绑定 roomService
:
public final void
onDestroy()
{
if(contextWeakReference != null)
{
final Context
context =
contextWeakReference
.get();
if(context != null)
{
if(roomServiceConnection != null)
{
if(boundToRoomService)
{
sendDBCloseMessageToRoomService();
context
.unbindService
(roomServiceConnection);
}
}
}
}
}
private void
sendDBCloseMessageToRoomService()
{
try
{
final Message message =
Message.obtain
(null, MSG_DB_CLOSE);
if(message != null)
{
if(messengerToRoomService != null)
{
messengerToRoomService
.send(message);
}
}
}
catch(final RemoteException e)
{
e.printStackTrace();
}
}
在 RoomService
中,我收到要关闭的消息 roomDatabase
:
public class RoomService
extends Service
{
@NonNull @NonNls public static final
String DATABASE_NAME = "room_database";
public static final int MSG_DB_CLOSE = 108;
@Nullable public RoomDatabase roomDatabase;
private final IBinder roomBinder = new Binder();
private WeakReference<Context> contextWeakReference;
@Nullable public Messenger messengerFromRoomService;
@Nullable public Messenger messengerToRoomService;
private static class RoomServiceHandler
extends Handler
{
@Nullable private final
WeakReference<RoomService> roomServiceWeakReference;
RoomServiceHandler
(@Nullable final
RoomService service)
{
if(service != null)
{
roomServiceWeakReference =
new WeakReference<RoomService>
(service);
}
else
{
roomServiceWeakReference = null;
}
}
@Override
public final void
handleMessage
(@Nullable final
Message message)
{
if(message != null)
{
final int what =
message.what;
switch(what)
{
case MSG_DB_CLOSE:
{
handleDBCloseMessage
(message);
break;
}
}
}
}
private void
handleDBCloseMessage
(@Nullable final
Message message)
{
if(message != null)
{
final RoomService
service =
roomServiceWeakReference
.get();
if(service != null)
{
if(service
.roomDatabase != null)
{
if(service
.roomDatabase
.isOpen())
{
service
.roomDatabase
.close();
}
}
}
}
}
}
@Override
public final void
onCreate()
{
super.onCreate();
// initialize application context weak reference
final Context
applicationContext =
getApplicationContext();
if(applicationContext != null)
{
contextWeakReference =
new WeakReference<Context>
(applicationContext);
// initialize database
roomDatabase =
Room
.databaseBuilder
(applicationContext,
MyRoomDatabase.class,
DATABASE_NAME)
.build();
if(roomDatabase != null)
{
// initialise your DAO here
yourDao =
roomDatabase
.yourDao();
}
}
final RoomServiceHandler
roomServiceHandler =
new RoomServiceHandler(this);
if(roomServiceHandler != null)
{
messengerToRoomService =
new Messenger(roomServiceHandler);
}
}
@Nullable
@Override
public final IBinder
onBind
(@Nullable final
Intent intent)
{
IBinder result = null;
if(messengerToRoomService != null)
{
final IBinder
roomBinder =
messengerToRoomService
.getBinder();
if(roomBinder != null)
{
result = roomBinder;
}
}
return result;
}
}