【问题标题】:Android ORMLite安卓 ORMLite
【发布时间】:2014-04-24 12:27:35
【问题描述】:

我正在为 android 4.47 使用 ormlite。 一切都很好,但有时在运行应用程序时我会收到下一个原因的异常:

you must call initialize() before you can use the dao

在我的应用程序类中,我是 init ormlite,就像写在文档中一样。

DatabaseFactory.setHelper(applicationContext);

发生了什么事? 我不经常收到这个例外。也许一天一个。

全栈:

 java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:300)
            at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
            at java.util.concurrent.FutureTask.run(FutureTask.java:242)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:841)
     Caused by: java.lang.IllegalStateException: you must call initialize() before you can use the dao
            at com.j256.ormlite.dao.BaseDaoImpl.checkForInitialized(BaseDaoImpl.java:925)
            at com.j256.ormlite.dao.BaseDaoImpl.queryBuilder(BaseDaoImpl.java:247)
            at com.j256.ormlite.dao.BaseForeignCollection.getPreparedQuery(BaseForeignCollection.java:174)
            at com.j256.ormlite.dao.EagerForeignCollection.<init>(EagerForeignCollection.java:38)
            at com.j256.ormlite.field.FieldType.buildForeignCollection(FieldType.java:784)
            at com.j256.ormlite.stmt.mapped.BaseMappedQuery.mapRow(BaseMappedQuery.java:82)
            at com.j256.ormlite.stmt.SelectIterator.getCurrent(SelectIterator.java:270)
            at com.j256.ormlite.stmt.SelectIterator.nextThrow(SelectIterator.java:161)
            at com.j256.ormlite.stmt.StatementExecutor.query(StatementExecutor.java:200)
            at com.j256.ormlite.stmt.StatementExecutor.queryForAll(StatementExecutor.java:118)
            at com.j256.ormlite.dao.BaseDaoImpl.queryForAll(BaseDaoImpl.java:239)
            at com.ls.dailysteals.core.database.dao.HeistDAO.getAllHeist(HeistDAO.java:31)
            at com.ls.dailysteals.ui.fragment.HeistFragment$1.doInBackground(HeistFragment.java:92)
            at com.ls.dailysteals.ui.fragment.HeistFragment$1.doInBackground(HeistFragment.java:88)
            at android.os.AsyncTask$2.call(AsyncTask.java:288)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:841)

初始化:

    public class DSApplication extends Application {

        private static Context applicationContext;

        @Override
        public void onCreate() {
            super.onCreate();
            DatabaseFactory.setHelper(applicationContext);
    }
}

第一次调用: 在片段生命周期方法 onViewCreated(...) 中调用;

databaseTask = new AsyncTask<Object, List<ShortDeal>, List<ShortDeal>>() {

            @Override
            protected List<ShortDeal> doInBackground(Object... params) {
                return DatabaseFactory.getHelper().getShortDealDAO().getAllShortDeal();
            }

            @Override
            protected void onPostExecute(List<ShortDeal> shortDeals) {
                super.onPostExecute(shortDeals);
                updateAdapter(shortDeals);
            }
        };

        if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
            databaseTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        } else {
            databaseTask.execute();
        }

【问题讨论】:

  • 听起来你有竞争条件。异常是从后台线程触发的。我的猜测是,在没有看到您的初始化代码的情况下,您正在主线程上初始化 DAO 并尝试在后台访问。访问经常发生在初始化之前:竞争条件。
  • 我能做什么?我需要后台线程中的 dao 类的对象?
  • 显示初始化 ORMLite 的代码。显示后台线程的启动位置。
  • 帖子已编辑,见顶部。

标签: android ormlite


【解决方案1】:

尝试使用

YourDao dao = new YourDao(OrmLiteSqliteOpenHelper.getConnectionSource(), YourDao.class);

public class YourDao extends BaseDaoImpl<YourClass, Integer> {    
    protected YourDao(ConnectionSource connectionSource, Class<YourClass> dataClass) throws SQLException {
        super(connectionSource, dataClass);
    }
}

改为

Dao<YourClass, Integer> yourDao = OrmLiteSqliteOpenHelper.getDao(YourClass.class);

在调用 YourDao.queryBuilder() 之前

BaseDaoImpl 的构造函数调用 initialize()

【讨论】:

    【解决方案2】:

    我从未使用过 ORMLite,但我猜这是因为您的 applicationContext 始终为空,因此它认为它没有被初始化

    public class DSApplication extends Application {
    
        private static Context applicationContext;
    
        @Override
        public void onCreate() {
            super.onCreate();
            applicationContext = this;
            DatabaseFactory.setHelper(this);
        }
        ....
    

    【讨论】:

    • 这是错误的,因为我很少收到错误。不总是。但是我尝试使用它,谢谢您的回答。
    • 也许您在其他地方也调用了 DatabaseFactory.setHelper(context) 并且在大多数情况下它在其他操作之前被调用所以它可以工作?
    • 不,这不包括在内!我有一个电话 DatabaseFactory.setHelper(context);在我的应用程序类中!
    • @smail2133 您的应用程序类中的一个还是整个项目中的一个?
    • 这是不正确的。这是线程之间的竞争条件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 2017-12-05
    • 2012-04-08
    • 2012-10-09
    • 2014-06-09
    相关资源
    最近更新 更多