当我通过Android工作室重新启动应用程序时,偶尔会出现此异常,我发现解决问题的唯一方法是清除应用程序中存储的数据。
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)
我认为这是因为应用程序在我的sqlite数据库的事务中被杀死。
编辑:
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;
}
}
SettingDataAccess.java
public class SettingTableData implements BaseColumns {
public static final String TABLE_NAME = "settings";
public static final String COLUMN_NAME_WIFIONLY = "wifiOnlyUpload";
public static final String COLUMN_NAME_USERNAME = "username";
public static final String COLUMN_NAME_ACCOUNTID = "accountId";
public static final String COLUMN_NAME_IDENTITYID = "identityId";
public static final String COLUMN_NAME_EMAIL = "email";
public static final String COLUMN_NAME_PREMIUM = "premium";
public static final String COLUMN_NAME_LASTREFRESH = "lastRefresh";
// public static final String COLUMN_NAME_PRIVATEKEY = "privateKey";
public static final String COLUMN_NAME_ADMINDEVICE = "admin";
public static final String COLUMN_NAME_PUBLICKEY = "publicKey";
public static final String COLUMN_NAME_TAKENAPSHOTS = "takeSnapshots";
public static final String COLUMN_NAME_AUTHSTATEJSON = "jsonAuthState";
}
SettingTableData.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();
}
}
Setting.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;
}
}
DataAccess.java
<style label="disable_continue" arg:timeout="3" mode="after" name="survey.respview.footer" with="q1, q2" wrap="ready">
<![CDATA[ var b=$ ("#btn_continue, #btn_finish");
b.disable();
setTimeout(function() {
b.enable();
postIt();
}
, $(timeout)*1000);
]]>
</style>
答案 0 :(得分:0)
看起来正在发生的事情是我的身份验证状态json字符串比我预期的要长得多。我把它移到了SharedPreference位置,一段时间后,每当我尝试加载OOM时,我都会开始获取OOM。我想这可能是在Sqlite中发生的事情。