当Realm在NotificationListenerService中更新时,不会调用RealmChangeListener

Ast*_*ixR 5 android realm

我在扩展的NotificationListenerService上进行Realm插入,如下所示:

public class NLService extends NotificationListenerService {

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {

        // building realmObject here

        mRealm = Realm.getDefaultInstance();
        RealmHelper.saveObj(myRealmObject, mRealm);
    //  mRealm.waitForChange(); / mRealm.refresh();
        mRealm.close();
    }
}


public class RealmHelper {

    public static RealmModel saveObj(RealmObject realmObject, Realm realm) {
        realm.beginTransaction();
        RealmObject newRealmObject = realm.copyToRealm(realmObject);
        realm.commitTransaction();
        return newRealmObject;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用领域比v0.88.3更新的,不是单一的RealmChangeListener(RCL如果有的话被插入)被调用NLService.

我试着将rcl直接附加到Realm,RealmResults并且RealmObject没有任何作用.

例如,应用程序具有简单的rcl RealmResults<myRealmObject>.size()和几个RecyclerAdapter,并且RealmRecyclerViewAdapter从不调用rcl内部.

然而,重新运行查询起作用并且显示"缺失数据".此外,如果在ui-或任何其他线程上插入了任何内容,则会调用rcl并显示"缺少数据".

我在Realm 0.88.3上呆了好几个月,因为我无法使用任何更新的Realm版本.在NLService mRealm.refresh();中调用了0.88.3,这在新版本中不可用并且.waitForChange无休止地阻塞.

的Manifest.xml:

<service
    android:name=".service.NLService"
    android:label="@string/nl_service"
    android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
    <intent-filter>
        <action android:name="android.service.notification.NotificationListenerService"/>
    </intent-filter>
</service>
Run Code Online (Sandbox Code Playgroud)

Epi*_*rce 15

我可以看到两个解决方案,要么使用looper线程(HandlerThread)和setAutoRefresh(true)(setAutoRefresh(false)之前调用Looper.quit()),要么强制刷新线程上的Realm实例.


注意:这依赖于包内部方法.谨防.

在v 1.1.1(和v1.2.0)中, - 和3.0.0之前的任何版本 - 而不是以下行

//  mRealm.waitForChange(); / mRealm.refresh();
Run Code Online (Sandbox Code Playgroud)

您可以HandlerController使用package-internal stuff 通过与Realm实例关联的强制更新本地线程

package io.realm;

public class RealmRefresh {
    public static void refreshRealm(Realm realm) {
        Message message = Message.obtain();
        message.what = HandlerControllerConstants.LOCAL_COMMIT;
        realm.handlerController.handleMessage(message);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后打电话

    mRealm = Realm.getDefaultInstance();
    RealmHelper.saveObj(myRealmObject, mRealm);
    RealmRefresh.refreshRealm(mRealm);
    mRealm.close();
Run Code Online (Sandbox Code Playgroud)

请注意更改日志的重大更改,因为0.89.0更改了迭代行为,并且在活动事务期间结果不再存在; 但是从3.0.0开始他们又来了.


但是,我还必须注意,如果您NotificationListenerService在远程进程中运行,那么Realm实例将无法相互通知.



编辑:

在Realm Java 3.0.0中,通知行为已完全更改,HandlerController不再存在.

相反,以下应该工作:

package io.realm;

public class RealmRefresh {
    public static void refreshRealm(Realm realm) {
        realm.sharedRealm.refresh();
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

在Realm 3.2.+中,这一切都可用

realm.refresh();
Run Code Online (Sandbox Code Playgroud)