2017-01-02 61 views
-1

,我發現我的問題的原因。不能回答我自己的問題,因爲它被標記爲重複的,但在我自己的問題下看到我的最後一條評論。我簡短地說,由於備份功能使用相同的版本號恢復了舊的數據庫方案,因此我的SQLiteHelperClass中都沒有調用onUpdate()或onCreate()方法。SQLlite「沒有這樣的列」新鮮的錯誤只有在簽署APK安裝

我遇到我解決不了一個奇怪的問題。當我在模擬器中運行我的應用程序時,一切都很好。當我運行它作爲我的手機上的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) 

如果我刪除所有設置中的應用程序數據重新運行應用程序,但所有應用程序都可以在簽名的應用程序版本中運行,儘管它首次安裝在手機上!

的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 + ")" 
    + ")" 

創建此錯誤的代碼如下:

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}); 

我的主要問題是colum LIST_ID,它似乎不是在簽名的apk的第一次安裝時創建的,但是如果我刪除應用程序數據並重新運行簽名的apk,則會創建該列。每次在模擬器上創建,並在手機上創建dubug.apk。

我已經試過:

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

,並修改了它一點點調試:

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

具有相同的錯誤結果。嘗試了不同的列,但listId是在所有情況下導致錯誤的列。但只有在手機上運行已簽名的apk時纔有效。如果這意味着任何問題,我的手機是三星S6。

隨着調試的措施,我想我的應用程序之前,強制數據庫的建立做任何事的這個代碼

SQLiteDatabase db = this.getWriteableDatabase(); 

它告訴我,數據庫沒有在第一次安裝時創建。事實上,儘管我的卸載工作看起來好像存在舊版數據庫。因此,我增加了數據庫版本,onUpgrade()在第一次安裝時被調用!

看起來好像數據庫在第一次安裝時沒有正確創建,因爲已簽名的apk或未正確卸載而未正確刪除。

我似乎無法在我的代碼或其他地方發現錯誤,我開始失明,但我希望別人可以看到錯誤或遇到類似此前的任何事情,並且可以將我推向正確的方向。

+0

你確定你已經刪除了應用程序並重新安裝了它,以確保沒有舊版本的數據是問題的原因嗎? –

+0

是的,很多次。一遍又一遍地。這只是簽署的構建行爲。 – user1086500

+0

記錄從全新安裝開始的每個sql create/select語句。在最壞的情況下,將這些線路發佈到錯誤(如果可能的話) - 也許有人可以發現一些東西。 –

回答

0

可能只是一個錯字,但你必須

The mytable is created by running db.execSQL(DATABASE_CREATE_MY_TABLE)

private static final String DATABASE_CREATE_MYTABLE = "CREATE TABLE " 
    + MY_TABLE + "("    
    + ID + " INTEGER, " 
    + LIST_ID + " INTEGER, " 
    + NAME + " STRING, " 
    + CONC + " REAL, " 
    + "PRIMARY KEY (" + ID + "," + LIST_ID + ")" 
    + ")" 

請注意,在第一個變量

+0

這是我的問題中的一種類型,而不是真正的代碼! ;-)然而,我的代碼在模擬器和apk-debug.apk版本中完美工作,但在構建簽名時沒有... – user1086500

2

額外的下劃線在這裏我要回答我的問題ownn。

我創建了一個已簽名的apk,以便在我的手機上測試它,以及從以前的版本升級時它是如何工作的。

在我的手機上,我也想嘗試一個「乾淨」的安裝,卸載並重新安裝,看看如何工作。然而這導致了問題中描述的錯誤。

原因是Android 6.0在manifest.xml中有allowBackup = true。這意味着,當您卸載應用程序時,所有數據都會在您重新安裝應用程序時進行備份和恢復。請參閱https://developer.android.com/guide/topics/data/autobackup.html

通常這是一件好事,但在調試我的應用程序時,我沒有將其用於解釋。由於備份的數據庫是相同的版本,但是與我試圖安裝的應用程序中的版本進行了一些修改,此功能使我的應用程序跳過了onCreate()和onUpgrade()。當我試圖讀取onCreate()或onUpgrade()創建的列時,我得到了我的錯誤。

+0

感謝兄弟,這解決了我試圖修復2天的問題!大啤酒給你! – jdabrowski