2017-03-06 97 views
0

當我通過Android Studio重新啓動應用程序時,偶爾會發生此異常,並且我發現要解決它的唯一方法是清除存儲在應用程序中的數據。重新啓動Android應用程序偶爾會拋出java.lang.IllegalStateException

java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. 

我想這是因爲應用程序在一個事務中,以我的SQLite數據庫被殺害。

  1. 我的假設是否正確?
  2. 有什麼辦法可以防止這種情況發生?
  3. 如果我的應用程序在前臺運行一個服務,並且爲了更新應用程序本身而死亡,這可能會發生嗎?

編輯:

STACK_TRACE=java.lang.RuntimeException: Unable to start activity ComponentInfo{com.camhart.netcountable/com.camhart.netcountable.activities.setup.DeviceTypeActivity}: java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3254) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3350) 
at android.app.ActivityThread.access$1100(ActivityThread.java:222) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:158) 
at android.app.ActivityThread.main(ActivityThread.java:7229) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 
Caused by: java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. 
at android.database.CursorWindow.nativeGetLong(Native Method) 
at android.database.CursorWindow.getLong(CursorWindow.java:524) 
at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:75) 
at com.camhart.netcountable.sqlite.dataaccess.SettingDataAccess.getSettings(SettingDataAccess.java:91) 
at com.camhart.netcountable.sqlite.businesslogic.SettingBusinessLogic.getSettingsFromDatabase(SettingBusinessLogic.java:61) 
at com.camhart.netcountable.sqlite.businesslogic.SettingBusinessLogic.getSetting(SettingBusinessLogic.java:54) 
at com.camhart.netcountable.activities.setup.DeviceTypeActivity.onCreate(DeviceTypeActivity.java:43) 
at android.app.Activity.performCreate(Activity.java:6876) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1135) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3207) 
... 9 more 
java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. 
at android.database.CursorWindow.nativeGetLong(Native Method) 
at android.database.CursorWindow.getLong(CursorWindow.java:524) 
at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:75) 
at com.camhart.netcountable.sqlite.dataaccess.SettingDataAccess.getSettings(SettingDataAccess.java:91) 
at com.camhart.netcountable.sqlite.businesslogic.SettingBusinessLogic.getSettingsFromDatabase(SettingBusinessLogic.java:61) 
at com.camhart.netcountable.sqlite.businesslogic.SettingBusinessLogic.getSetting(SettingBusinessLogic.java:54) 
at com.camhart.netcountable.activities.setup.DeviceTypeActivity.onCreate(DeviceTypeActivity.java:43) 
at android.app.Activity.performCreate(Activity.java:6876) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1135) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3207) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3350) 
at android.app.ActivityThread.access$1100(ActivityThread.java:222) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:158) 
at android.app.ActivityThread.main(ActivityThread.java:7229) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 

SettingDataAccess.java

package com.camhart.netcountable.sqlite.dataaccess; 

import android.content.ContentValues; 
import android.content.Context; 
import android.database.Cursor; 

import com.camhart.netcountable.sqlite.models.Setting; 
import com.camhart.netcountable.sqlite.tabledata.SettingTableData; 

import net.openid.appauth.AuthState; 

import org.json.JSONException; 

public class SettingDataAccess extends DataAccess { 

    \\... 

    private static String[] columnsToGrab = new String[]{ 
      SettingTableData._ID, 
      SettingTableData.COLUMN_NAME_USERNAME, 
      SettingTableData.COLUMN_NAME_ACCOUNTID, 
      SettingTableData.COLUMN_NAME_IDENTITYID, 
      SettingTableData.COLUMN_NAME_WIFIONLY, 
      SettingTableData.COLUMN_NAME_EMAIL, 
      SettingTableData.COLUMN_NAME_ADMINDEVICE, 
      SettingTableData.COLUMN_NAME_PREMIUM, 
      SettingTableData.COLUMN_NAME_PUBLICKEY, 
      SettingTableData.COLUMN_NAME_TAKENAPSHOTS, 
      SettingTableData.COLUMN_NAME_AUTHSTATEJSON 
    }; 

    public Setting getSettings() { 
     Setting setting = new Setting(); 

     Cursor c = db.query(SettingTableData.TABLE_NAME, 
       columnsToGrab, 
       null, 
       new String[]{}, 
       null, 
       null, 
       null, 
       null); 

     if(c.moveToFirst()) { 
      setting.setId(c.getLong(c.getColumnIndex(SettingTableData._ID))); //#line 91 
      setting.setAccountId(c.getString(c.getColumnIndex(SettingTableData.COLUMN_NAME_ACCOUNTID))); 
      setting.setIdentityId(c.getString(c.getColumnIndex(SettingTableData.COLUMN_NAME_IDENTITYID))); 
      setting.setDisplayName(c.getString(c.getColumnIndex(SettingTableData.COLUMN_NAME_USERNAME))); 
      setting.setWifiOnlyUpload(c.getInt(c.getColumnIndex(SettingTableData.COLUMN_NAME_WIFIONLY)) == 1); 
      setting.setEmail(c.getString(c.getColumnIndex(SettingTableData.COLUMN_NAME_EMAIL))); 

      setting.setAdminDevice(c.getInt(c.getColumnIndex(SettingTableData.COLUMN_NAME_ADMINDEVICE)) == 1); 
      setting.setPremium(c.getInt(c.getColumnIndex(SettingTableData.COLUMN_NAME_PREMIUM)) == 1); 
      setting.setPublicKey(c.getString(c.getColumnIndex(SettingTableData.COLUMN_NAME_PUBLICKEY))); 
      setting.setTakeSnapshots(c.getInt(c.getColumnIndex(SettingTableData.COLUMN_NAME_TAKENAPSHOTS)) == 1); 
      String jsonAuthState = c.getString(c.getColumnIndex(SettingTableData.COLUMN_NAME_AUTHSTATEJSON)); 

      if(jsonAuthState != null) { 
       try { 
        setting.setAuthState(AuthState.jsonDeserialize(jsonAuthState)); 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } 
      c.close(); 

      return setting; 
     } 
     c.close(); 

     return null; 
    } 
} 

SettingTableData.java

​​

Setting.java

public class Setting { 

    private boolean wifiOnlyUpload; 
    private String displayName; 
    private String accountId; 
    private String identityId; 
    private long id; 
    private String email; 
    private boolean premium; 
    private boolean adminDevice; 
    private String publicKey; 
    private boolean takeSnapshots; 
    private AuthState authState; 

    public String getIdentityId() { 
     return identityId; 
    } 

    public void setIdentityId(String identityId) { 
     this.identityId = identityId; 
    } 

    public String getAccountId() { 
     return accountId; 
    } 

    public void setAccountId(String accountId) { 
     this.accountId = accountId; 
    } 

    public boolean isWifiOnlyUpload() { 
     return wifiOnlyUpload; 
    } 

    public void setWifiOnlyUpload(boolean wifiOnlyUpload) { 
     this.wifiOnlyUpload = wifiOnlyUpload; 
    } 

    public String getDisplayName() { 
     return displayName; 
    } 

    public void setDisplayName(String username) { 
     this.displayName = username; 
    } 

    public long getId() { 
     return id; 
    } 

    public void setId(long id) { 
     this.id = id; 
    } 

    public void setEmail(String email) { 
     this.email = email; 
    } 

    public String getEmail() { 
     return email; 
    } 

    public boolean isPremium() { 
     return premium; 
    } 

    public void setPremium(boolean premium) { 
     this.premium = premium; 
    } 

    public boolean isAdminDevice() { 
     return adminDevice; 
    } 

    public void setAdminDevice(boolean adminDevice) { 
     this.adminDevice = adminDevice; 
    } 

    public void setPublicKey(String publicToken) { 
     this.publicKey = publicToken; 
    } 

    public String getPublicKey() { 
     return this.publicKey; 
    } 

    public boolean takesSnapshots() { 
     //TODO: Make it so admins can take screenies too (for couples) 
     return isTakeSnapshots() && isPremium(); 
    } 

    public void setTakeSnapshots(boolean takeSnapshots) { 
     this.takeSnapshots = takeSnapshots; 
    } 

    public boolean isTakeSnapshots() { 
     return takeSnapshots; 
    } 

    public AuthState getAuthState() { 
     return authState; 
    } 

    public void setAuthState(AuthState jsonAuthState) { 
     this.authState = jsonAuthState; 
    } 

    //TODO: update this to save the device type, then just have this check for isOwnerDevice instead of 
    // having to check the auth state too. 
    public boolean isOwner() { 
     return getAuthState() != null && isAdminDevice(); 
    } 

    public String getReversedIdentityId() { 
     return new StringBuilder(getIdentityId()).reverse().toString(); 
    } 
} 

DataAccess.java

public class DataAccess { 
    protected SQLiteDatabase db; 
    private static DbHelper dbHandler; 

    protected static synchronized DbHelper getDbHelper(Context context) { 
     if(dbHandler == null) { 
      dbHandler = new DbHelper(context); 
     } 
     return dbHandler; 
    } 

    public DataAccess(Context context) { 
     if(dbHandler == null) { 
      dbHandler = getDbHelper(context); 
     } 
    } 

    public void open() throws SQLException { 
     db = dbHandler.getWritableDatabase(); 
    } 

    public void close() { 
     db.close(); 
     db = null; 
    } 
} 
+0

我們需要更多信息來幫助您。請發佈整個堆棧跟蹤和任何相關的代碼。 –

+0

這與交易無關。 –

+0

我在等待錯誤再次發生,然後我將用代碼和完整的堆棧跟蹤進行更新。 – CamHart

回答

0

這似乎發生了什麼事是我的身份驗證狀態的JSON字符串是比我預期這將是非常非常長。我將它移到了SharedPreference位置,過了一段時間,我試圖加載它時就開始獲得OOM。我認爲這可能是在Sqlite中發生的。

相關問題