【问题标题】:Room running very slow房间运行很慢
【发布时间】:2018-06-30 12:54:56
【问题描述】:

我正在尝试使用 Room Persistence Library 获取/存储数据。从表中获取所有数据的调用非常慢,我使用nanoTime 将其计时为大约 1800 毫秒,我认为这太慢了。可能出了什么问题?

这里有更多信息:

  1. 表中只有 20-30 个条目。
  2. 20 个字段,其中一些由 Gson 序列化。 Gson 不是瓶颈(nanoTime 表示)
  3. 测试设备运行 6.0 (Xperia M5)
  4. 房间 v1.1.1
  5. 查询正在使用AsyncTask 运行

查询在 DbDao 中定义为

@Query("SELECT * FROM events")
List<Event> getAllEvents();

【问题讨论】:

  • 你能找出问题所在吗?

标签: android sqlite android-room


【解决方案1】:

异步任务不适合处理 Room 数据库。我建议您使用 executor 并使用它创建一个单例类。代码如下。 导入android.os.Looper; 导入android.support.annotation.NonNull;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class AppExecutor {
    private static final Object LOCK = new Object();
    private static AppExecutor sInstance;
    private final Executor diskIO;
    private final Executor mainThread;
    private final Executor networkIO;

    public AppExecutor(Executor diskIO, Executor mainThread,
                       Executor networkIO) {
        this.diskIO = diskIO;
        this.mainThread = mainThread;
        this.networkIO = networkIO;
    }

    public static AppExecutor getInstance() {
        if (sInstance == null) {
            synchronized (LOCK) {
                sInstance = new AppExecutor(Executors.newSingleThreadExecutor(),
                      Executors.newFixedThreadPool(3), new MainThreadExecutor());
            }
        }
        return sInstance;
    }

    public Executor diskIO() {
        return diskIO;
    }

    public Executor mainThread() {
        return mainThread;
    }

    public Executor networkIO() {
        return networkIO;
    }

    private static class MainThreadExecutor implements Executor {
        private android.os.Handler mainThreadHandler =
                new android.os.Handler(Looper.getMainLooper());

        @Override
        public void execute(@NonNull Runnable runnable) {
        }
    }
}

现在,在创建这个新类之后,在 appexecutor 线程中执行所有数据库访问功能。这比使用异步任务和内置 java 线程库要好。还要确保任何数据访问函数都不会在 UI 线程上运行。 如果您发布了更多代码,我将能够查明确切的问题。 最后一件事在您的代码中使用它,如下所示-

AppExecutor.getInstance().diskIO().execute(new Runnable() {
    @Override
    public void run() {
        ///Your data access task////
    }
});

【讨论】:

  • "这比使用异步任务和内置 java 线程库要好。"具体怎么样?
  • 如您所见,我正在使用线程池执行器线程池解决了两个不同的问题:由于减少了每个任务的调用开销,它们通常在执行大量异步任务时提供改进的性能,并且它们提供一种限制和管理执行任务集合时消耗的资源(包括线程)的方法。简而言之,我们知道在手机中保存数据并检索它对于异步任务来说是一项非常可怕的任务。 Executors也是android架构组件的主要部分,性能比异步任务好很多。
  • Java 线程库也很难管理。线程池执行器为管理部分完成所有工作
  • 感谢您的回答,假设后台运行的数据访问任务已经完成,我应该如何更新ui?我可以直接调用runOnUithread还是有其他更好的方法@雅利安索尼
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-12
相关资源
最近更新 更多