gpt4 book ai didi

android - Android 3.0+ 问题上的 db4o

转载 作者:太空狗 更新时间:2023-10-29 12:54:13 26 4
gpt4 key购买 nike

我在 Android 3.0+ 上遇到 db4o 的问题,因为事实证明,在创建 db4o 数据库时,它默认使用一些网络 api。 (我偶然发现了这篇文章:http://mavistechchannel.wordpress.com/2011/11/18/db4o-at-honeycomb-and-ice-cream-sandwich/ 关于它)

但是,我试图使数据库创建请求异步,但我认为我遇到了在数据库完全创建之前调用数据库的问题,因为它锁定了数据库。 (现在我得到一个锁定错误)有什么办法可以同步吗?或者,至少要等到它完成?这是我的 db4o 助手:

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 Context context;

/**
* @param ctx
*/

public Db4oHelperAsync(Context ctx) {
context = ctx;
}

/**
* Create, open and close the database
*/
public ObjectContainer db() {


if (oc == null || oc.ext().isClosed()) {

if (Utilities.getPreferences(context).getBoolean(USE_INTERNAL_MEMORY_FOR_DATABASE, true)) {

new GetDbFromInternalMemory().execute();

} else {
new GetDbFromSDCard().execute();
}
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() {
if (oc != null)
oc.close();
}

private class GetDbFromInternalMemory extends AsyncTask<Void, Void, ObjectContainer>{

@Override
protected ObjectContainer doInBackground(Void... params) {
try {
ObjectContainer obj = Db4oEmbedded.openFile(dbConfig(), db4oDBFullPathInternal(context));
CLog.v("USING INTERNAL MEMORY FOR DATABASE");
return obj;

} catch (Exception ie) {
ie.printStackTrace();
CLog.e(Db4oHelper.class.getName(), ie.toString());
return null;
}
}

@Override
protected void onPostExecute(ObjectContainer result)
{
oc = result;
}
}

private class GetDbFromSDCard extends AsyncTask<Void, Void, ObjectContainer>{

@Override
protected ObjectContainer doInBackground(Void... params) {
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();

return obj;

} catch (Exception ie) {
ie.printStackTrace();
CLog.e(Db4oHelper.class.getName(), ie.toString());
return null;
}
}

@Override
protected void onPostExecute(ObjectContainer result)
{
oc = result;
}
}
}

最佳答案

更新:这db4o bug has been fixed .如果您获得最新的 8.1 位,则不应发生错误并且解决方法是绝对的:

尝试获取数据库时遇到文件锁定异常?对。

好吧,问题是您没有等待异步任务完成,而是开始一个新任务,以防 Db4oHelperAsync.oc 为空。您基本上必须等到初始化完成,然后才使用 Db4oHelperAsync.oc 变量。所以您在 Java 同步领域。

例如,您可以这样做:同步 Db4oHelperAsync.oc 访问。请求数据库时,等待变量设置。现在不幸的是我不知道异步任务的确切行为。我的猜测是它将在主要 Activity 上运行 .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());
}
}
}
}

附言将此问题作为错误添加到 db4o:http://tracker.db4o.com/browse/COR-2269

关于android - Android 3.0+ 问题上的 db4o,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8578408/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com