android – Realm.io和异步查询

前端之家收集整理的这篇文章主要介绍了android – Realm.io和异步查询前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们开始在 Android应用程序项目中使用Realm.io.但是我们不喜欢Realm.io API的一点是没有任何异步方式来查询数据库.在旧项目中我们使用DbQuery和sqlite,因此我们习惯在线程或AsyncTask中进行数据库查询.但令人非常不安的是,在所有示例中,查询都是在UiThread中进行的.对于应用程序性能来说这不是一件坏事吗?我们尝试在线程或AsyncTasks中进行查询,但是当我们在UiThread中访问我们的模型对象时,我们得到一个错误,说我们无法在查询它们的线程中访问RealObjects.这是我们的示例代码
service.getDatabaseHelper()
            .with(getActivity()) //Context that I use to instance the Realm instance
            .onFinishQuery( new DatabaseHelper.IQueryGetCallback<UserRealm>() {
                @Override
                public void onGetResult(UserRealm[] results) {
                    for(UserRealm aUser : results){
                        //Here is where it crashes
                        Log.d("Log","Username -> "+aUser.getName());
                    }
                }
            })
            .getUsersFromDb();
//.......

//In our "DAO" class
public void getUsersFromDb(){
    new GetQueryTask() {
        @Override
        public UserRealm[] onQueryReadyToBeExecuted(Realm realmInstance) {
            RealmQuery<UserRealm> query = realmInstance.where(UserRealm.class);
            RealmResults<UserRealm> result = query.findAll();
            // TODO hacer que devuelva un array

            ArrayList<UserRealm> users = new ArrayList<UserRealm>();
            for (UserRealm u : result) {
                //Here we can read the RealObject's fine
                users.add(u);
            }
            return users.toArray(new UserRealm[users.size()]);
        }
    }.execute();
}

//Our abstract task that wraps all the instantiation-transaction behavIoUr
public abstract class GetQueryTask<T extends RealmObject> extends AsyncTask<Void,Void,T[]> {
    @Override
    protected T[] doInBackground(Void... params) {
        //We tried to instantiate this class in several places,here
        //Send it as parameter through the AsyncTask
        //context is set in the with(Context ctx) method.
        Realm realm = Realm.getInstance(context);
        return onQueryReadyToBeExecuted(realm);
    }

    public abstract T[] onQueryReadyToBeExecuted(Realm realmInstance);

    @Override
    protected void onPostExecute(T[] result) {
        mCallback.onExecute(result);
    }
}

我们主要担心的不是这段代码的“bug”,而是可以像在Realm.io开发人员的示例中那样在UiThread中进行查询.如果是这种情况,那么异步执行查询的所有代码将不再是必需的.

解决方法

来自境界的基督徒在这里.
您是正确的,当前需要在其使用的线程上运行查询,这可能会对UI线程性能产生负面影响.然而,我们敏锐地意识到这一点,并且正在积极致力于跨线程移动查询结果.

即使对于合理的大量数据,Realm中的查询也非常快,并且由于它只加载实际使用的数据,即使在UI线程上运行也可以非常高效.

我鼓励您尝试使用您认为合理的任何数据大小并测试您的性能(最好在较旧的设备上:)).也可以做一些技巧,比如向键添加索引,在后台线程上进行繁重的查询,将键发送到UI线程并在那里重新查询.它是一个绑带,但在某些情况下会起作用 – 尽管可能不适合列表.

猜你在找的Android相关文章