Android OrmLite - queryForId()方法中的OOM错误

时间:2014-08-07 08:45:46

标签: android sqlite ormlite

我在Android应用中使用OrmLite和SQLite数据库。目前我正在处理queryForId(String arg0)方法中发生的OOM错误。

堆栈跟踪:

java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
at java.util.concurrent.FutureTask.run(FutureTask.java:239)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:841) Caused by: java.lang.OutOfMemoryError
at android.database.CursorWindow.nativeGetString(Native Method)
at android.database.CursorWindow.getString(CursorWindow.java:438)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
at com.j256.ormlite.android.AndroidDatabaseResults.getString(AndroidDatabaseResults.java:134)
at com.j256.ormlite.field.types.StringType.resultToSqlArg(StringType.java:39)
at com.j256.ormlite.field.BaseFieldConverter.resultToJava(BaseFieldConverter.java:24)
at com.j256.ormlite.field.FieldType.resultToJava(FieldType.java:819)
at com.j256.ormlite.stmt.mapped.BaseMappedQuery.mapRow(BaseMappedQuery.java:60)
at com.j256.ormlite.android.AndroidDatabaseConnection.queryForOne(AndroidDatabaseConnection.java:196)
at com.j256.ormlite.stmt.mapped.MappedQueryForId.execute(MappedQueryForId.java:38)
at com.j256.ormlite.stmt.StatementExecutor.queryForId(StatementExecutor.java:85)
at com.j256.ormlite.dao.BaseDaoImpl.queryForId(BaseDaoImpl.java:223)
at com.myapp.db.DatabaseManager.getResponseWithId(DatabaseManager.java:123)
at com.myapp.async.AsyncBaseProxy$ExecuteBaseProxyTask.doInBackground(AsyncBaseProxy.java:321)
at com.myapp.async.AsyncBaseProxy$ExecuteBaseProxyTask.doInBackground(AsyncBaseProxy.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
... 3 more

DatabaseManager.java

synchronized public Response getResponseWithId(String idExt) {
    Response response = null;
    try {
        response = getHelper().getResponseDao().queryForId(idExt);
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return response;
}

第123行是

response = getHelper().getResponseDao().queryForId(idExt);

我在AsyncTask中执行上面的方法。

DatabaseHelper.java

public Dao<Response, String> getResponseDao() {
    if (null == responseDao) {
        try {
            responseDao = getDao(Response.class);
        } catch (java.sql.SQLException e) {
            e.printStackTrace();
        }
    }
    return responseDao;
}

Response.java

@DatabaseTable
public class Response {

@DatabaseField(id = true)
private String id;
@DatabaseField
private String response;
@DatabaseField
private long lastTime;
@DatabaseField
private boolean isNeedForRefresh;
@DatabaseField
private int errorCode;
@DatabaseField
private String eTag;

private boolean notModified;
private SuccessObject success;

public Response() {
}

public Response(String id) {
    this.id = id;
    this.errorCode = -1;
}

/** Getters and setters below **/

}

知道如何解决这个问题吗?我可以做些什么优化? 提前谢谢。

1 个答案:

答案 0 :(得分:-1)

SQLite不是线程安全的。所以你必须只在主线程中调用sqlite函数。看看:http://www.sqlite.org/faq.html#q6