Bev*_*vor 1 android sqliteopenhelper android-sqlite
首先,这里所有类似的帖子都没有帮助.
在AsyncTask中,我检查应用程序启动是否是第一次启动,这意味着我检查是否有数据库.我希望通过表格查询来做到这一点.这是正在执行的内容:
@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;
}
Run Code Online (Sandbox Code Playgroud)
与IllegalArgumentException崩溃:数据库未打开发生在此行上.
SQLiteDatabase db = defaultSQLiteOpenHelper.getWritableDatabase();
Run Code Online (Sandbox Code Playgroud)
它恰好发生在方法(见下文)createAllTables上.
该文件说:
创建和/或打开将用于读写的数据库.第一次调用它时,将打开数据库并调用onCreate(SQLiteDatabase),onUpgrade(SQLiteDatabase,int,int)和/或onOpen(SQLiteDatabase).
在我看来,它应该执行我的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();
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,为什么不打开数据库?文档说它必须.我不接受任何脏的解决方法作为手动打开数据库或其他东西的解决方案.我的代码究竟出了什么问题?我无法相信它是Android中的一个错误.
这是堆栈跟踪:
05-27 17:25:50.370:I/DefaultSQLiteOpenHelper(719):未找到数据库.生成新数据库... 05-27 17:25:50.400:W/dalvikvm(719):threadid = 10:线程退出未捕获异常(组= 0x40015560)05-27 17:25:50.400:E/AndroidRuntime(719) ):致命异常:AsyncTask
1 05-27 17:25:50.400:E/AndroidRuntime(719):java.lang.RuntimeException:执行时发生错误
doInBackground()05-27 17:25:50.400:E/AndroidRuntime(719):at android.os.AsyncTask $ 3.done(AsyncTask.java:200)05-27 17:25:50.400:E/AndroidRuntime(719) :at java.util.concurrent.FutureTask $ Sync.innerSetException(FutureTask.java:274)05-27 17:25:50.400:E/AndroidRuntime(719):at java.util.concurrent.FutureTask.setException(FutureTask.java :125)05-27 17:25:50.400:E/AndroidRuntime(719):at java.util.concurrent.FutureTask $ Sync.innerRun(FutureTask.java:308)05-27 17:25:50.400:E/AndroidRuntime (719):at java.util.concurrent.FutureTask.run(FutureTask.java:138)05-27 17:25:50.400:E/AndroidRuntime(719):at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor. java:1088)05-27 17:25:50.400:E/AndroidRuntime(719):at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:581)05-27 17:25:50.400:E/AndroidRuntime(719):at java.lang.Thread.run(Thread.java:1019)05-27 17:25:50.400:E/AndroidRuntime(719):引起:java.lang.IllegalStateException:database not op en 05-27 17:25:50.400:E/AndroidRuntime(719):在android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:555)05-27 17:25:50.400:E/AndroidRuntime(719):在android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:137)05-27 17:25:50.400:E/AndroidRuntime(719):at com.mydomain.android.base.persistence.PersistenceManager.loadAll(PersistenceManager. java:58)05-27 17:25:50.400:E/AndroidRuntime(719):at com.mydomain.android.base.main.StartupTask.isFirstStartAfterInstallation(StartupTask.java:107)05-27 17:25:50.400: E/AndroidRuntime(719):at com.mydomain.android.base.main.StartupTask.doInBackground(StartupTask.java:52)05-27 17:25:50.400:E/AndroidRuntime(719):at com.mydomain.android .base.main.StartupTask.doInBackground(StartupTask.java:18)05-27 17:25:50.400:E/AndroidRuntime(719):at android.os.AsyncTask $ 2.call(AsyncTask.java:185)05-27 17:25:50.400:E/AndroidRuntime(719):at java.util.concurrent.FutureTask $ Sync.innerRun(FutureTask.java:306)0 5-27 17:25:50.400:E/AndroidRuntime(719):...还有4个
首先,您要关闭数据库createAllTables().切勿关闭数据库onCreate()或onUpgrade()的SQLiteOpenHelper.
其次,您的事务逻辑是不必要的createAllTables(),就像onCreate()在事务中执行一样.这很好,因为无论如何,您的事务逻辑都是不正确实现的.
为澄清后一条评论,进行交易的正确方法是:
try {
db.beginTransaction();
// SQL
db.setTransactionSuccessful();
}
// optional catch block
finally {
db.endTransaction();
}
Run Code Online (Sandbox Code Playgroud)
endTransaction()如果存在SQL异常,则需要调用 - 您的实现会跳过此异常.
| 归档时间: |
|
| 查看次数: |
1939 次 |
| 最近记录: |