运行 Room 的推荐方法 Insert in another thread in kotlin

Recommended way to run Room Insert in another thread in kotlin

我正处于 Repository 我想将 运行 @Insert 实现到一个新线程中的步骤,而不是在 UI 线程中。

我看到有几种方法可以解决这个问题:

  1. 一些示例使用 AsyncTask 并在 doInBackground 内执行 Dao 调用

  2. Google 向日葵样本使用 runOnIoThread,这是一种执行 IO_EXECUTOR.execute(job) 的方法,其中 IO_EXECUTOR = Executors.newSingleThreadExecutor

  3. 好像有人用anko

doAsync{ dao.insert(item) }

推荐的方法是什么?

您通常应该将自己的执行器封装在一个接口下。

public interface Scheduler {
    void runOnThread(Runnable runnable);
}

/**
 * A Scheduler implementation based on ModernAsyncTask with an unbounded task queue.
 **/
public class IoScheduler implements Scheduler {
    private static final int CORE_POOL_SIZE = 5;
    private static final int MAXIMUM_POOL_SIZE = 128;
    private static final int KEEP_ALIVE = 1;

    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "IoScheduler #" + mCount.getAndIncrement());
        }
    };

    private static final BlockingQueue<Runnable> sPoolWorkQueue =
            new LinkedBlockingQueue<Runnable>();

    /**
     * An {@link Executor} that can be used to execute tasks in parallel.
     */
    private static final Executor THREAD_POOL_EXECUTOR =
         new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
                 TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

    @Override
    public void runOnThread(Runnable runnable) {
        THREAD_POOL_EXECUTOR.execute(runnable);
    }
}

你通常用 Dagger 提供这些:

@Singleton
public class IoScheduler implements Scheduler {
    @Inject
    IoScheduler() {}
    ...
}

@Module
public class SchedulerModule {
    public static final String BACKGROUND = "BACKGROUND";

    @Named(BACKGROUND) // you can also use @Qualifier
    @Provides
    Scheduler ioScheduler(IoScheduler ioScheduler) {
        return ioScheduler;
    }
}

然后在别处使用

@Singleton
public class MyService {
    private final Scheduler ioScheduler;

    @Inject
    MyService(@Named(SchedulerModule.BACKGROUND) Scheduler ioScheduler) { // you can use @Qualifier here instead of @Named
        this.ioScheduler = ioScheduler;
    }
    ....
}

(虽然这个 ioScheduler 更适合读取:对于写入,您可能需要考虑一个单独的单线程执行程序。)


所以如果你读到最后,实际上是这样的方法:

2.) The Google sunflower sample uses runOnIoThread which is a method that does IO_EXECUTOR.execute(job) where IO_EXECUTOR = Executors.newSingleThreadExecutor