我有一个在SQLite中存储数据的服务。我希望该服务在应用程序关闭时继续运行。 (向外滑动)但是当销毁应用程序时,getInstance()会返回null。即使申请被关闭,我怎样才能保持活力?
我的数据库单例类:
public class DbManager {
private static DbManager instance;
private CipherDbHelper dbHelper;
private DbManager() {
}
private DbManager(Context context, String password) {
SQLiteDatabase.loadLibs(context);
dbHelper = new CipherDbHelper(context, password);
}
public static void init(Context context, String password) {
instance = new DbManager(context, password);
}
public static DbManager getInstance() {
if (instance == null) {
Log.e("DbManager", "Can't access DbManager : instance is null.")
}
return instance;
}
//Closing
public void closeDatabase() {
dbHelper.close();
dbHelper = null;
instance = null;
}
public <D extends Dao<T, String>, T> D getDAO(Class<T> clz) throws SQLException {
return dbHelper.getDao(clz);
}
}
答案 0 :(得分:1)
步骤1:删除closeDatabase()
以及任何调用它的代码。
步骤2:让getDatabase()
返回null
而不是抛出异常,或让它抛出自定义异常而不是IllegalArgumentException
。
步骤3:如果服务从其null
电话中获得getDatabase()
(或者它捕获了您的自定义例外),请让它引发Notification
告诉用户“我需要你再次登录“并跳过它应该做的任何工作。
从根本上说,您遇到了一个架构问题:Android进程是短暂的。其结果是在后台使用加密数据库通常是不可能的。一旦流程结束,您将无法访问数据库(使用用户的密码解锁),需要用户再次登录。
您可以使用前台服务(通过startForeground()
)来减少进程终止的可能性,但这会给用户带来成本(始终可见Notification
,可能会导致CPU过多用于非真实背景的工作等。)。
答案 1 :(得分:0)
要在后台运行任务,您需要使用Service。
在致电X
之前,请致电Y
;因为在您调用DBManager.init(context)
方法之前,您的实例仍为DBManager.getInstance()
。
答案 2 :(得分:0)
对于使用单例类来获取帮助程序实例的服务访问SQLite数据库(加密或未加密)的相同问题。以下是我解决问题的方法。只需将服务的上下文传递给SQLiteHelper,再次加载lib并重新生成帮助程序实例。然后,一旦关闭应用程序(通过刷掉它),它就不会被销毁
在我的例子中,我在我的服务的onCreate方法上调用了它:
DbManager.init(TrackingService.this, "examplePassword"));