Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/228.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 为什么SQLiteOpenHelper会导致IllegalArgumentException数据库未打开?_Android_Android Sqlite_Sqliteopenhelper - Fatal编程技术网

Android 为什么SQLiteOpenHelper会导致IllegalArgumentException数据库未打开?

Android 为什么SQLiteOpenHelper会导致IllegalArgumentException数据库未打开?,android,android-sqlite,sqliteopenhelper,Android,Android Sqlite,Sqliteopenhelper,首先,这里所有类似的帖子都没有帮助 在异步任务中,我检查应用程序启动是否是第一次启动,这意味着我检查是否有数据库。我想通过从表中查询来实现这一点。这就是正在执行的内容: @Override public List<Entity> loadAll(Entity markerEntity) { Log.i(TAG, "trying to load all entities of type " + markerEntity.getTable()); List<Ent

首先,这里所有类似的帖子都没有帮助

在异步任务中,我检查应用程序启动是否是第一次启动,这意味着我检查是否有数据库。我想通过从表中查询来实现这一点。这就是正在执行的内容:

@Override
public List<Entity> loadAll(Entity markerEntity)
{
    Log.i(TAG, "trying to load all entities of type " + markerEntity.getTable());

    List<Entity> results = new LinkedList<Entity>();

    SQLiteDatabase db = defaultSQLiteOpenHelper.getWritableDatabase();

    Cursor cursor = db.query(markerEntity.getTable(), markerEntity.getAllColumns(), null, null, null, null, null);    
    cursor.moveToFirst();

    while (!cursor.isAfterLast())
    {
        Entity result = markerEntity.createNewInstance(cursor);
        results.add(result);

        cursor.moveToNext();
    }

    db.close();

    return results;
}
它正好发生在方法上,请参见下面的createAllTables

报告说:

创建和/或打开将用于读取和 写第一次调用它时,将打开数据库 和onCreateSQLiteDatabase,onUpgradeSQLiteDatabase,int,int 和/或将调用onOpenSQLiteDatabase

在我看来,它应该执行我的DefaultSQLiteOpenhelper并创建所有数据库表,但它没有这样做:

public class DefaultSQLiteOpenHelper extends SQLiteOpenHelper implements ISQLiteOpenHelper
{
    private static final String TAG = DefaultSQLiteOpenHelper.class.getSimpleName();

    private static final String DATABASE_NAME = "MY_DATABASE";
    private static final int DATABASE_VERSION = 1;

    @Inject
    public DefaultSQLiteOpenHelper(Context context)
    {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    //is called by the framework if the database doesn't exist
    @Override
    public void onCreate(SQLiteDatabase db)
    {
        Log.i(TAG, "no database found. Generating new database...");

        createAllTables(db);    
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    {
         Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion);
//       db.execSQL("DROP TABLE IF EXISTS " + TABLE_COMMENTS); ///TODO when upgrade
//       onCreate(db);
    }

    //The order must not be changed because sqlite doesn't allow
    //table modification. That means one cannot add constraints afterwards
    //which results in creating tables in a specific order
    private final void createAllTables(SQLiteDatabase db)
    {
        db.beginTransaction();

        //create lookups at first
        db.execSQL(TableFactory.createUsage());
        db.execSQL(TableFactory.createLanguage());

        db.execSQL(TableFactory.createAccount());
        db.execSQL(TableFactory.createPreferences());
        db.execSQL(TableFactory.createLanguageUsageRel());
        db.execSQL(TableFactory.createPantry());
        db.execSQL(TableFactory.createProduct());

        //populate lookups
        db.execSQL(DataFactory.populateUsage());
        db.execSQL(DataFactory.populateLanguage());

        db.setTransactionSuccessful();
        db.endTransaction();
        db.close();
    }
}
问题是,为什么它不打开一个数据库?文件上说必须这样做。我不接受任何肮脏的解决方法,比如手动打开数据库之类。我的代码到底出了什么问题?我不敢相信这是安卓系统的一个bug

以下是stacktrace:

05-27 17:25:50.370:I/DefaultSQLiteOpenHelper719:未找到数据库。 正在生成新数据库。。。05-27 17:25:50.400:W/dalvikvm719: threadid=10:线程退出时未捕获异常组=0x40015560 05-27 17:25:50.400:E/AndroidRuntime719:致命异常:异步任务

1 05-27 17:25:50.400:E/AndroidRuntime719:java.lang.RuntimeException:执行时出错 doInBackground 05-27 17:25:50.400:E/AndroidRuntime719:at android.os.AsyncTask$3.doneAsyncTask.java:200 05-27 17:25:50.400: E/AndroidRuntime719:at java.util.concurrent.FutureTask$Sync.innerSetExceptionFutureTask.java:274 05-27 17:25:50.400:E/AndroidRuntime719:at java.util.concurrent.FutureTask.setExceptionFutureTask.java:125 05-27 17:25:50.400:E/AndroidRuntime719:at java.util.concurrent.FutureTask$Sync.innerRunFutureTask.java:308 05-27 17:25:50.400:E/AndroidRuntime719:at java.util.concurrent.FutureTask.runFutureTask.java:138 05-27 17:25:50.400:E/AndroidRuntime719:at java.util.concurrent.ThreadPoolExecutor.runWorkerThreadPoolExecutor.java:1088 05-27 17:25:50.400:E/AndroidRuntime719:at java.util.concurrent.ThreadPoolExecutor$Worker.runThreadPoolExecutor.java:581 05-27 17:25:50.400:E/AndroidRuntime719:at java:1019 05-27 17:25:50.400: E/AndroidRuntime719:原因:java.lang.IllegalStateException: 数据库未打开05-27 17:25:50.400:E/AndroidRuntime719:at android.database.sqlite.SQLiteDatabase.endTransactionSQLiteDatabase.java:555 05-27 17:25:50.400:E/AndroidRuntime719:at android.database.sqlite.SQLiteOpenHelper.getWritableDatabaseSQLiteOpenHelper.java:137 05-27 17:25:50.400:E/AndroidRuntime719:at com.mydomain.android.base.persistence.PersistenceManager.loadAllPersistenceManager.java:58 05-27 17:25:50.400:E/AndroidRuntime719:at com.mydomain.android.base.main.StartupTask.isFirstStartAfterInstallationStartupTask.java:107 05-27 17:25:50.400:E/AndroidRuntime719:at com.mydomain.android.base.main.StartupTask.doInBackgroundStartupTask.java:52 05-27 17:25:50.400:E/AndroidRuntime719:at com.mydomain.android.base.main.StartupTask.doInBackgroundStartupTask.java:18 05-27 17:25:50.400:E/AndroidRuntime719:at android.os.AsyncTask$2.callAsyncTask.java:185 05-27 17:25:50.400: E/AndroidRuntime719:at java.util.concurrent.FutureTask$Sync.innerRunFutureTask.java:306 05-27 17:25:50.400:E/AndroidRuntime719:。。。4更多


首先,关闭createAllTables中的数据库。决不要从SQLiteOpenHelper的onCreate或onUpgrade关闭数据库

其次,在createAllTables中不需要事务逻辑,因为onCreate是在事务中执行的。这很好,因为无论如何,您的事务逻辑实现不正确

为了澄清后一种意见,正确的交易方式是:

try {
    db.beginTransaction();

    // SQL

    db.setTransactionSuccessful();
}
// optional catch block
finally {
    db.endTransaction();
}

如果存在SQL异常,则需要调用endTransaction—您的实现将跳过该异常。

首先,您要关闭createAllTables中的数据库。决不要从SQLiteOpenHelper的onCreate或onUpgrade关闭数据库

其次,在createAllTables中不需要事务逻辑,因为onCreate是在事务中执行的。这很好,因为无论如何,您的事务逻辑实现不正确

为了澄清后一种意见,正确的交易方式是:

try {
    db.beginTransaction();

    // SQL

    db.setTransactionSuccessful();
}
// optional catch block
finally {
    db.endTransaction();
}

如果有SQL异常,则需要调用终结事务。

您可能会考虑发布堆栈跟踪。@普通SWISE在这里是..dB.Calm在OnCuto中是不正确的。您可以考虑发布堆栈跟踪。@普通SWISE在这里是.dB.Calm在OnCuto中是不正确的。@AyncTask中的可写数据库?我很想说,它可能会导致并发异常。你能告诉我这个吗?@CommmonsWare T
汉克斯,真是个愚蠢的错误顺便问一下:您的意思是,对于未正确实现的情况,尽管在这个示例中我不需要它,但这是错误的事务处理方式吗?我在save方法中执行了类似的操作。@user2336315:允许在AyncTask中获取可写数据库吗?-它不仅是允许的,而且几乎是强制性的,因为如果必须创建或更新数据库,getWriteableDatabase可以执行重要的磁盘I/O。我很想说,它可能会导致并发异常正如您通过查看源代码所看到的,它同步了这项工作。@commonware谢谢,很高兴看到我已经在save方法中以这种方式完成了这项工作。@CommmonsWare允许在AyncTask中获取可写数据库吗?我很想说,它可能会导致并发异常。你能告诉我这个吗?@谢谢,这是个多么愚蠢的错误顺便问一下:您的意思是,对于未正确实现的情况,尽管在这个示例中我不需要它,但这是错误的事务处理方式吗?我在save方法中执行了类似的操作。@user2336315:允许在AyncTask中获取可写数据库吗?-它不仅是允许的,而且几乎是强制性的,因为如果必须创建或更新数据库,getWriteableDatabase可以执行重要的磁盘I/O。我很想说,它可能会导致并发异常正如您通过查看源代码所看到的,它同步了这项工作。@commonware谢谢,很高兴看到我已经在save方法中以这种方式完成了这项工作。