JobSchedulerService 中的 RoomDB
RoomDB in JobSchedulerService
我最近通过 JobService 将 JobScheduler 添加到我的应用程序中。我使用 JobService 在后台定期与我的数据库同步并更新本地 Room DB 实例。
但是,我看到任意崩溃并出现以下错误:
Process: com.application.name, PID: 27229
java.lang.RuntimeException: Unable to instantiate service com.application.name.Services.SyncService:
java.lang.NullPointerException: Attempt to invoke virtual method
'android.content.Context
android.content.Context.getApplicationContext()' on a null object
reference
完整的堆栈跟踪如下:
Caused by java.lang.NullPointerException: Attempt to invoke virtual
method 'android.content.Context
android.content.Context.getApplicationContext()' on a null object
reference
at com.application.name.Database.AppDatabase.getDatabase(AppDatabase.java:38)
at com.application.name.Services.SyncService.(SyncService.java:48)
at java.lang.Class.newInstance(Class.java)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3551)
at android.app.ActivityThread.-wrap4(Unknown Source)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1778)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6798)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
崩溃报告突出显示的违规行是 JobService 构造函数中 Room DB 实例的实例化。
public SyncService() {
super();
database = AppDatabase.getDatabase(getApplication());
}
在 Room DAO 中,我有以下代码:
private static AppDatabase INSTANCE;
public static AppDatabase getDatabase(final Context context){
if(INSTANCE == null) {
synchronized (AppDatabase.class){
if(INSTANCE == null){
// Migration definitions go here
..
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
AppDatabase.class, context.getResources().getString(R.string.database))
.allowMainThreadQueries()
.addMigrations(FROM_2_TO_3)
.build();
}
}
}
return INSTANCE;
}
所以我想我明白为什么会发生这种情况 - 当应用程序不是 运行 时,应用程序上下文为 Null,因此 Room 的数据库构建器在设置时遇到问题。
我想知道的是,如果没有应用程序 运行,是否有某种方法可以访问我的 Room DB。将 Context 传递给 JobService 的初始化并编写辅助构造函数似乎是一个丑陋的 hack,可能会产生不可预测的情况,所以我想知道我还有哪些其他选择。
我可以做的一件事是将从 JobService 检索到的数据写入 SharedPreferences,然后在应用程序启动时将其同步到数据库。还有别的办法吗?
我想我错过了一个简单的事实 - a Service IS a Context.
而不是传递:
database = AppDatabase.getDatabase(getApplication());
我需要做的就是:
database = AppDatabase.getDatabase(this);
到目前为止,我还没有遇到任何反复发生的崩溃……。我仍然对其他答案持开放态度,所以如果您认为我可以以更好的方式做到这一点,请加入您的观点。
applicationContext
应该在调用 onCrate()
方法之后调用。因此,您需要 运行 您的代码在 onCreate()
方法中。
我最近通过 JobService 将 JobScheduler 添加到我的应用程序中。我使用 JobService 在后台定期与我的数据库同步并更新本地 Room DB 实例。
但是,我看到任意崩溃并出现以下错误:
Process: com.application.name, PID: 27229 java.lang.RuntimeException: Unable to instantiate service com.application.name.Services.SyncService: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
完整的堆栈跟踪如下:
Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference at com.application.name.Database.AppDatabase.getDatabase(AppDatabase.java:38) at com.application.name.Services.SyncService.(SyncService.java:48) at java.lang.Class.newInstance(Class.java) at android.app.ActivityThread.handleCreateService(ActivityThread.java:3551) at android.app.ActivityThread.-wrap4(Unknown Source) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1778) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6798) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
崩溃报告突出显示的违规行是 JobService 构造函数中 Room DB 实例的实例化。
public SyncService() {
super();
database = AppDatabase.getDatabase(getApplication());
}
在 Room DAO 中,我有以下代码:
private static AppDatabase INSTANCE;
public static AppDatabase getDatabase(final Context context){
if(INSTANCE == null) {
synchronized (AppDatabase.class){
if(INSTANCE == null){
// Migration definitions go here
..
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
AppDatabase.class, context.getResources().getString(R.string.database))
.allowMainThreadQueries()
.addMigrations(FROM_2_TO_3)
.build();
}
}
}
return INSTANCE;
}
所以我想我明白为什么会发生这种情况 - 当应用程序不是 运行 时,应用程序上下文为 Null,因此 Room 的数据库构建器在设置时遇到问题。
我想知道的是,如果没有应用程序 运行,是否有某种方法可以访问我的 Room DB。将 Context 传递给 JobService 的初始化并编写辅助构造函数似乎是一个丑陋的 hack,可能会产生不可预测的情况,所以我想知道我还有哪些其他选择。
我可以做的一件事是将从 JobService 检索到的数据写入 SharedPreferences,然后在应用程序启动时将其同步到数据库。还有别的办法吗?
我想我错过了一个简单的事实 - a Service IS a Context.
而不是传递:
database = AppDatabase.getDatabase(getApplication());
我需要做的就是:
database = AppDatabase.getDatabase(this);
到目前为止,我还没有遇到任何反复发生的崩溃……。我仍然对其他答案持开放态度,所以如果您认为我可以以更好的方式做到这一点,请加入您的观点。
applicationContext
应该在调用 onCrate()
方法之后调用。因此,您需要 运行 您的代码在 onCreate()
方法中。