Mar*_*rqs 8 sqlite android android-asynctask sqliteopenhelper
我有一个问题,我不知道如何处理它.我的应用中的一项活动有多个AsyncTask
s访问单个SQLiteOpenHelper
.我初始化并打开帮助程序onCreate()
,我正在关闭它onStop()
.我还检查它是否已经初始化onResume()
.
由于我已经发布了我的应用程序,因此doInBackground
在尝试访问数据库帮助程序时,我收到了Null Exception错误的数量.我知道这是因为DB onStop()
在doInBackground
被调用之前就已经关闭了(公平).
我的问题是,我应该在哪里关闭数据库连接?在Activity中使用DB帮助程序的单个实例并从多个线程(AsyncTasks
)访问它是正确的吗?或者我应该为每个使用单独的DB帮助程序实例AsyncTask
?
这是我活动的简化骨架:
public class MyActivity extends Activity{
private DbHelper mDbHelper;
private ArrayList<ExampleObject> objects;
@Override
public void onStop(){
super.onStop();
if(mDbHelper != null){
mDbHelper.close();
mDbHelper = null;
}
}
@Override
public void onResume(){
super.onResume();
if(mDbHelper == null){
mDbHelper = new DbHelper(this);
mDbHelper.open();
}
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
DbHelper mDbHelper = new DbHelper(this);
mDbHelper.open();
}
private class DoSomething extends AsyncTask<String, Void, Void> {
@Override
protected Void doInBackground(String... arg0) {
objects = mDbHelper.getMyExampleObjects();
return null;
}
@Override
protected void onPostExecute(final Void unused){
//update UI with my objects
}
}
private class DoSomethingElse extends AsyncTask<String, Void, Void> {
@Override
protected Void doInBackground(String... arg0) {
objects = mDbHelper.getSortedObjects();
return null;
}
@Override
protected void onPostExecute(final Void unused){
//update UI with my objects
}
}
}
Run Code Online (Sandbox Code Playgroud)
Dmi*_*nko 11
您不需要为每个活动管理数据库连接.您可以在android.app.Application的实例中执行此操作,并使用此实例访问db.像这样的东西:
public class MyApplication extends Application {
// Synchronized because it's possible to get a race condition here
// if db is accessed from different threads. This synchronization can be optimized
// thought I wander if it's necessary
public synchronized static SQLiteDatabase db() {
if(self().mDbOpenHelper == null) {
self().mDbOpenHelper = new MyDbOpenHelper();
}
return self().mDbOpenHelper.getWritableDatabase();
}
public static Context context() {
return self();
}
@Override
public void onCreate() {
super.onCreate();
mSelf = this;
}
private static MyApplication self() {
if (self == null) throw new IllegalStateException();
return mSelf;
}
private MyDbOpenHelper mDbOpenHelper;
private static MyApplication mSelf;
}
Run Code Online (Sandbox Code Playgroud)
这样您就可以确定Db始终可以访问.
是的,有一个Db助手的实例是一个很好的做法.默认情况下,线程同步是为您完成的.
使用单个是好的DB Helper
.问题是,当用户离开时,Activity
它DB
仍然关闭但AsyncTask
可能仍在运行.因此,DB
当您尝试访问它时,应该检查它是否为空,如果是null
这样,则可能意味着您Activity
已被销毁并且cancel
该任务.
小智 1
您提到在关闭数据库之前取消 AsyncTask。但您应该记住,取消 AsyncTask 只是发出要取消任务的信号,您需要检查 doInBackground() 中的 isCancelled() 并执行必要的操作来停止数据库操作。
在关闭数据库之前,您需要检查 getStatus() 以确保 AsyncTask 已停止。