SQLlite'没有这样的列'错误仅在全新安装的签名APK中

use*_*500 0 sqlite android android-sqlite

我找到了问题的原因,见下文!

简而言之,由于备份功能恢复了具有相同版本号的旧数据库方案,因此在我的SQLiteHelperClass中都没有调用onUpdate()或onCreate().

我遇到了一个我无法解决的奇怪问题.当我在模拟器中运行我的应用程序时,一切正常.当我在手机上将其作为apk-debug.apk运行时,一切正常,但当我尝试在手机上将其作为已签名的应用程序运行时,我收到此错误:

Error Code : 1 (SQLITE_ERROR)
Caused By : SQL(query) error or missing database.
(no such column: listId (code 1): , while compiling: SELECT * FROM mytable WHERE listId=100 ORDER BY id,name,conc ASC)
Run Code Online (Sandbox Code Playgroud)

如果我删除设置中的所有应用程序数据并重新运行应用程序,一切都在签名的应用程序版本中工作,尽管它最初是首次安装在手机上!

mytable是通过运行db.execSQL(DATABASE_CREATE_MY_TABLE)创建的:(列名是在其他地方设置的常量)

private static final String DATABASE_CREATE_MY_TABLE = "CREATE TABLE "
    + MY_TABLE + "("             
    + ID + " INTEGER, "
    + LIST_ID + " INTEGER, "
    + NAME + " STRING, "
    + CONC + " REAL, "
    + "PRIMARY KEY (" + ID + "," + LIST_ID + ")"
    + ")"
Run Code Online (Sandbox Code Playgroud)

创建此错误的代码如下:

    SQLiteDatabase db = this.getReadableDatabase();
    String selectQuery = "SELECT * FROM " + MY_TABLE + " WHERE " + LIST_ID + "=?" + " ORDER BY " + NAME + "," + CONC + " ASC";
    Cursor cursor = db.rawQuery(selectQuery, new String[] {listId});
Run Code Online (Sandbox Code Playgroud)

我的主要问题是colum LIST_ID似乎不是在第一次安装签名的apk时创建的,但是如果我删除了app-data并重新运行签名的apk就会创建.每次在模拟器上创建并在手机上创建dubug.apk.

我试过了:

String selectQuery = "SELECT * FROM " + MY_TABLE + " WHERE " + LIST_ID + "=" + listId + " ORDER BY " + NAME + "," + CONC + " ASC";
Cursor cursor = db.rawQuery(selectQuery, null);
Run Code Online (Sandbox Code Playgroud)

并修改了一点调试:

String selectQuery = "SELECT * FROM " + MY_TABLE + " WHERE " + ID + "=?" + LIST_ID + "=?" + " ORDER BY " + NAME + "," + CONC + " ASC";
Cursor cursor = db.rawQuery(selectQuery, new String[] {id, listId});
Run Code Online (Sandbox Code Playgroud)

结果有同样的错误.尝试了不同的列,但listId是在所有情况下导致错误的列.但只有在我的手机上运行签名的apk时.我的手机是三星S6,如果这意味着anythig.

作为一种调试措施,我尝试在我的应用程序使用此代码执行任何操作之前强制创建数据库

SQLiteDatabase db = this.getWriteableDatabase();
Run Code Online (Sandbox Code Playgroud)

这告诉我数据库不是在第一次安装时创建的.实际上,尽管我的卸载努力,似乎存在旧版本的数据库.因此,我增加了数据库版本,并在首次安装时调用了onUpgrade()!

似乎数据库在首次安装时未正确创建为已签名的apk或未通过卸载正确删除.

我似乎无法在我的代码中找到错误或者其他地方,我开始失明,但我希望其他人可以看到这个错误或者之前经历过这样的事情并且可以让我朝着正确的方向前进.

use*_*500 5

我会在这里回答我自己的问题.

我创建了一个签名的apk,以便在我的手机上测试它以及从以前的版本升级时它是如何工作的.

在我的手机上,我还想尝试"干净"安装,卸载并重新安装,看看它是如何工作的.然而,这导致了问题中描述的错误.

原因是Android 6.0在manifest.xml中有allowBackup = true.这意味着当您卸载应用程序时,所有数据都会在您重新安装应用程序时进行备份和重试.请参阅https://developer.android.com/guide/topics/data/autobackup.html

通常情况下这是一件好事,但在调试我的应用程序时,我没有把它变成这种方式.此功能使我的应用程序跳过onCreate()和onUpgrade(),因为备份的数据库是相同的版本,但有一些修改,因为我尝试安装的应用程序中的版本.当我尝试读取onCreate()或onUpgrade()都没有创建的列时,我收到了错误消息.