適切な同時操作を行う方法がわからないので、コードを調整しようとしました。そして、コンストラクターでの並行性と、静的な最終フィールドとの並行性が完全に失われました...
public static class Connection {
private final CustomerDatabaseOpenHelper mHelper;
private SQLiteDatabase mDatabase;
private String mUserId;
private AtomicInteger mOpenCounter;
public Connection(Context context, String userId) {
mHelper = CustomerDatabaseOpenHelper.getInstance(context, DB_NAME, null, DB_VERSION);
mOpenCounter = mHelper.mOpenCounter;
mUserId = userId;
}
public void open() throws SQLException {
// open database in reading/writing mode
int value = mOpenCounter.incrementAndGet();
if(value == 1 || mDatabase==null || mUserId ==null) {
// Opening new database
Log.v("tugce","open new customer db");
mDatabase = mHelper.getWritableDatabase();
}
};
public void close() {
int value = mOpenCounter.decrementAndGet();
if(value == 0) {
// Closing database
if (mDatabase != null) {
try {
Log.v("tugce","close customer db");
mDatabase.close();
mDatabase = null;
mUserId = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
//私のopenhelperクラス
public class CustomerDatabaseOpenHelper extends SQLiteOpenHelper{
public AtomicInteger mOpenCounter = new AtomicInteger();
public static CustomerDatabaseOpenHelper mInstance;
public static synchronized CustomerDatabaseOpenHelper getInstance(Context context, String name,
CursorFactory factory, int version) {
if (mInstance == null) {
mInstance = new CustomerDatabaseOpenHelper(context, name, factory, version);
}
return mInstance;
}
private CustomerDatabaseOpenHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
}
これは私がスレッドで使用している方法です:
class MyGetPlanedCallList extends
AsyncTask<Object, Object, List<MyPlannedCallListItem>> {
CustomerDatabase.Connection mDbCon = new CustomerDatabase.Connection(InstanceActivity.this, mUserId);
@Override
protected void onPreExecute() {
mDbCon.open();
}
@Override
protected List<MyPlannedCallListItem> doInBackground(Object... params) {
mDbCon.doSomeStuff();
}
@Override
protected void onPostExecute(List<MyPlannedCallListItem> result) {
mDbCon.close();
}
@Override
protected void onCancelled() {
if (mDbCon != null)
mDbCon.close();
}
}
私が望むのは、他のインスタンスが作業している場合、まったく同じデータベースを閉じてはならないということです。
どんな助けでも大歓迎です。