Обновление: эта ошибка db4o была исправлена . Если вы получите новейшие 8,1 битов, ошибка не должна возникать, и обходной путь является абсолютным:
Вы получаете исключение, заблокированное файлом, при попытке получить базу данных? Право.
Ну, проблема в том, что вы не ждете завершения асинхронной задачи и просто запускаете новую, если Db4oHelperAsync.oc имеет значение null. В основном вам нужно подождать, пока инициализация не закончится, и только затем использовать переменную Db4oHelperAsync.oc. Таким образом, ваша земля синхронизации Java.
Например, вы можете сделать это: Синхронизировать доступ Db4oHelperAsync.oc. При запросе базы данных подождите, пока переменная не будет установлена. Сейчас, к сожалению, я не знаю точное поведение асинхронной задачи. Я предполагаю, что он запустит метод .onPostExecute () обратно к основному действию. Это также означает, что вы не можете просто ждать этого, потому что это будет означать, что вы блокируете Activity-Thread, и .onPostExecute () никогда не будет выполняться.
Вот мой набросок того, что я бы попытался сделать. Я никогда не выполнял и не компилировал это. И это, вероятно, имеет проблемы с синхронизацией. Например, если инициализация не удалась, она просто повесит ваше приложение на вызов .db (), потому что оно ждет вечно. Так что будьте очень осторожны и постарайтесь улучшить это:
public class Db4oHelperAsync implements Constants{
private static final String USE_INTERNAL_MEMORY_FOR_DATABASE = "USE_INTERNAL_MEMORY_FOR_DATABASE";
private static ObjectContainer oc = null;
private static final Object lock = new Object();
private Context context;
/**
* @param ctx
*/
public Db4oHelperAsync(Context ctx) {
context = ctx;
}
/**
* Create, open and close the database
*/
public ObjectContainer db() {
synchronized(lock){
if (oc == null || oc.ext().isClosed()) {
if (Utilities.getPreferences(context).getBoolean(USE_INTERNAL_MEMORY_FOR_DATABASE, true)) {
new GetDbFromInternalMemory().start();
} else {
new GetDbFromSDCard().start();
}
while(oc==null){
this.wait()
}
return oc;
} else {
return oc;
}
}
}
/**
* Configure the behavior of the database
*/
private EmbeddedConfiguration dbConfig() throws IOException {
EmbeddedConfiguration configuration = Db4oEmbedded.newConfiguration();
configuration.common().objectClass(PersistentObjectWithCascadeOnDelete.class).objectField("name").indexed(true);
configuration.common().objectClass(PersistentObjectWithCascadeOnDelete.class).cascadeOnUpdate(true);
configuration.common().objectClass(PersistentObjectWithCascadeOnDelete.class).cascadeOnActivate(true);
configuration.common().objectClass(PersistentObjectWithCascadeOnDelete.class).cascadeOnDelete(true);
configuration.common().objectClass(PersistentObjectWithoutCascadeOnDelete.class).objectField("name").indexed(true);
configuration.common().objectClass(PersistentObjectWithoutCascadeOnDelete.class).cascadeOnUpdate(true);
configuration.common().objectClass(PersistentObjectWithoutCascadeOnDelete.class).cascadeOnActivate(true);
return configuration;
}
/**
* Returns the path for the database location
*/
private String db4oDBFullPathInternal(Context ctx) {
return ctx.getDir("data", 0) + "/" + "testapp.db4o";
}
private String db4oDBFullPathSdCard(Context ctx) {
File path = new File(Environment.getExternalStorageDirectory(), ".testapp");
if (!path.exists()) {
path.mkdir();
}
return path + "/" + "testapp.db4o";
}
/**
* Closes the database
*/
public void close() {
synchronized(lock){
if (oc != null)
oc.close();
}
}
private class GetDbFromInternalMemory extends Thread{
@Override
protected void run() {
try {
ObjectContainer obj = Db4oEmbedded.openFile(dbConfig(), db4oDBFullPathInternal(context));
CLog.v("USING INTERNAL MEMORY FOR DATABASE");
synchronized(Db4oHelperAsync.lock){
Db4oHelperAsync.oc = obj;
Db4oHelperAsync.lock.notifyAll()
}
} catch (Exception ie) {
ie.printStackTrace();
CLog.e(Db4oHelper.class.getName(), ie.toString());
}
}
}
private class GetDbFromSDCard extends Thread{
@Override
protected void run() {
try {
ObjectContainer obj = Db4oEmbedded.openFile(dbConfig(), db4oDBFullPathSdCard(context));
CLog.v("USING SDCARD FOR DATABASE");
SharedPreferences.Editor edit = Utilities.getPreferencesEditor(context);
edit.putBoolean(USE_INTERNAL_MEMORY_FOR_DATABASE, true);
edit.commit();
synchronized(Db4oHelperAsync.lock){
Db4oHelperAsync.oc = obj;
Db4oHelperAsync.lock.notifyAll()
}
} catch (Exception ie) {
ie.printStackTrace();
CLog.e(Db4oHelper.class.getName(), ie.toString());
}
}
}
}
P.S. Добавил эту проблему как ошибку в db4o: http://tracker.db4o.com/browse/COR-2269