【问题标题】:realm and IntentService领域和 IntentService
【发布时间】:2016-05-25 17:08:46
【问题描述】:

我已经填写了领域数据库。一切正常。

应用程序有一个按钮,按下它会启动 IntentService。测试很简单

代码在这里

public class HNotificationService extends IntentService {
    public HNotificationService() {
        super("HNotificationService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.d("HNotificationService", "onHandleIntent");

        Realm realm = Realm.getDefaultInstance();
        RealmResults<HPartner> mResPartner = realm.where(HPartner.class).findAll();
        final HPartner hPartner = mResPartner.get(0);
        realm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                hPartner.setName("test");
            }
        });
        realm.close();
    }
}

这段代码执行后,数据库变空了!我在日志中看不到任何错误。

注意。仅当我想记录某些内容时才会清理数据库。 我会很高兴得到任何帮助

EDIT1

内部应用程序类。我用这个代码

  RealmConfiguration config = new RealmConfiguration.Builder(this).build();
  Realm.setDefaultConfiguration(config);

EDIT2

是的,你是对的,数据库没有被删除!

Log.e("HNotificationService", "empty"); - 从不调用,很好

        Realm realm = Realm.getDefaultInstance();
        RealmResults<HPartner> mResPartner = realm.where(HPartner.class).findAll();
        if (mResPartner.size() > 0) {
            Log.e("HNotificationService", "don't empty!");
        }

        final HPartner hPartner = mResPartner.get(0);
        realm.executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                hPartner.setName("test");
            }
        });

        mResPartner = realm.where(HPartner.class).findAll();
        if (mResPartner.size() == 0) {
            Log.e("HNotificationService", "empty");
        }

        realm.removeAllChangeListeners();
        realm.close();

另一个原因。当我转到另一个屏幕时,我正在调用代码

        mResPartners = Realm.getDefaultInstance().where(HPartner.class).findAllAsync();
        mResPartners.removeChangeListeners();
        mResPartners.addChangeListener(mPartnersListener);

并且永远不会调用 mPartnersListener。这很奇怪。 如果不运行 IntentService。 mPartnersListener 总是被调用

编辑 3

 mPartnersListener = new RealmChangeListener<RealmResults<HPartner>>() {
            @Override
            public void onChange(RealmResults<HPartner> realmResult) {
                mResPartners.removeChangeListeners();
                mClusterManager.clearItems();
                mGoogleMap.clear();
                if (realmResult != null && realmResult.size() > 0) {
                    mListPartners = realmResult;
                    getLoaderManager().restartLoader(LMarkerIcons.ID_LOADER, null, FrAroundMeMap.this);
                }
            }
        };

【问题讨论】:

  • 这看起来很正常。你的领域配置是什么?
  • 执行该代码后如何检测 Realm 为空?
  • 您确定您首先将 HPartner 添加到 DB 吗? realm.executeTransaction 保留机制以捕获 Exeption(如果发生)并取消事务。要找出问题,你可以使用登录。检查 HPartner 表的大小等,记录每一步。你怎么知道你的数据库变空了?
  • @Christian Melchior 请参阅edit2
  • @Vladymyr R.tmnko 请参阅edit2

标签: android realm intentservice


【解决方案1】:

我想,我发现了问题!在这部分登录后,您删除了 IntentService 中的 allChangelisteners。

mResPartner = realm.where(HPartner.class).findAll();
    if (mResPartner.size() == 0) {
        Log.e("HNotificationService", "empty");
    }

    realm.removeAllChangeListeners();
    realm.close();

然后您进行新查询,添加 NEW changeListener 并希望从他那里获取通知,但是在发送通知之后,侦听器被上面的代码删除。

将 changelistener 添加到异步获取的 realmResult - 正确,应该可以正常工作! 所以在 IntentService 中删除这个块

realm.removeAllChangeListeners();

而且你的听众看起来很奇怪,请参阅你的 onChange

中的评论
mPartnersListener = new RealmChangeListener<RealmResults<HPartner>>() {
        @Override
        public void onChange(RealmResults<HPartner> realmResult) {

            // here U remove listener BEFORE do your stuff and 
            // onChange will never called again 
            // If U`ll put log here U find out, that listener was called
            // simple delete block -> mResPartners.removeChangeListeners(); 

            mResPartners.removeChangeListeners(); 
            mClusterManager.clearItems();
            mGoogleMap.clear();
            if (realmResult != null && realmResult.size() > 0) {
                mListPartners = realmResult;
                getLoaderManager().restartLoader(LMarkerIcons.ID_LOADER, null, FrAroundMeMap.this);
            }
        }
    };

【讨论】:

  • 我喜欢的问题。如果我使用 Service - ChangeListener 工作得很好。如果我使用 IntentService - ChangeListener 坏了!!! IntentService - 它有一个单独的线程。我认为这是问题的原因
  • 服务在启动时运行在同一个线程上(UI 线程)。 IntentService 在第二个 Looper 线程上运行。我想知道 looper 是否可以以某种方式从 UI 线程“窃取” REALM_CHANGED 消息。 @ChristianMelchior ?
  • 不,我们在所有 Looper 线程上都有一个 Realm 内部列表,每个 Looper 都有自己的消息。
【解决方案2】:

在这段代码中让我感到困惑的是,您应该在事务中获取最新版本的领域对象

@Override
protected void onHandleIntent(Intent intent) {
    Log.d("HNotificationService", "onHandleIntent");

    Realm realm = Realm.getDefaultInstance();
    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            RealmResults<HPartner> mResPartner = realm.where(HPartner.class).findAll();
            final HPartner hPartner = mResPartner.get(0);
            hPartner.setName("test");
        }
    });
    realm.close();
}

除此之外,我会尝试将 async() 查询替换为同步版本。

mResPartners = Realm.getDefaultInstance().where(HPartner.class).findAll();

另外值得注意的是Realm.getDefaultInstance().where( 这个结构意味着你永远无法在 UI 线程上关闭领域。

编辑:你确定

            mResPartners.removeChangeListeners();

不会在您的更改监听器中引起任何问题吗?

【讨论】:

  • 您不必在事务中获取最新版本的领域对象!事务必须包含以某种方式修改数据库数据的代码,并尽可能快地提交!
  • findAllAsync - 我很晚才打电话。这里是 ChangeListener 的问题,他们不会在 IntentService 之后调用。很奇怪!!!
  • 你试过我说的了吗。
  • 我喜欢的问题。如果我使用 Service - ChangeListener 工作得很好。如果我使用 IntentService - ChangeListener 坏了!!! IntentService - 它有一个单独的线程。我认为这是问题的原因
  • 在单独的线程上应该不是问题,但我想知道与 IntentService 自己的线程关联的 Looper 和 Handler 是否有问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-04
  • 2014-01-19
  • 1970-01-01
  • 1970-01-01
  • 2011-04-25
相关资源
最近更新 更多