如何避免在我的 Android Room 存储库中出现许多 AsyncTask class?

How to avoid occurring many AsyncTask class in my Android Room repository?

我正在学习如何使用 google-developer-training 的 Android Room,我在其中找到了 repository class 的示例。我尝试简化我的 SportRepository class。我想知道如何避免在我的代码中重复 inner class ...AsyncTask。这是非常示例的示例:

@Singleton
class SportRepository {
    val LOG_TAG = SportRepository::class.java.name

    @Inject
    lateinit var sportDAO: SportDAO
    var list: LiveData<List<Sport>>

    init {
        App.app().appComponent()?.inject(this)
        list = sportDAO.getAll()
    }

    fun insert(sport: Sport) {
        insertAsyncTask().execute(sport)
    }

    fun update(sport: Sport){
        updateAsyncTask().execute(sport)
    }

    fun delete(sport: Sport) {
        deleteAsyncTask().execute(sport)
    }

    @SuppressLint("StaticFieldLeak")
    private inner class insertAsyncTask() : AsyncTask<Sport, Void, Void>() {
        override fun doInBackground(vararg p0: Sport): Void? {
            sportDAO.insert(p0.get(0))
            return null
        }
    }

    @SuppressLint("StaticFieldLeak")
    private inner class updateAsyncTask() : AsyncTask<Sport, Void, Void>() {
        override fun doInBackground(vararg p0: Sport): Void? {
            sportDAO.update(p0[0])
            return null
        }
    }

    @SuppressLint("StaticFieldLeak")
    private inner class deleteAsyncTask() : AsyncTask<Sport, Void, Void>() {
        override fun doInBackground(vararg p0: Sport): Void? {
            sportDAO.delete(p0[0])
            return null
        }
    }
}

AsyncTaskclasses 仅在名称和从 sportDAO class 调用的方法类型上有所不同。

有什么方法可以避免创建许多几乎相同的 AsyncTask classes?

我还没有找到任何如何简化它的例子。

好的,我遇到了同样的情况。我使用了 3 种解决方案。 1.使用RX。 Return 一个Flowable,在不同的线程上观察它。 2. 使用实时数据。 3.异步任务。这就是我如何通过使用泛型来避免多个异步任务。希望这就是您要找的。

这是将执行您的查询的 class。

/**
 *
 * @param <T> type of result expected
 */
public abstract class DaoAsyncProcessor<T> {

    public interface DaoProcessCallback<T>{
        void  onResult(T result);
    }

    private DaoProcessCallback daoProcessCallback;

    public DaoAsyncProcessor(DaoProcessCallback daoProcessCallback) {
        this.daoProcessCallback = daoProcessCallback;
    }

    protected abstract T doAsync();

    public void start(){
        new DaoProcessAsyncTask().execute();
    }

    private class DaoProcessAsyncTask extends AsyncTask<Void, Void, T>{

        @Override
        protected T doInBackground(Void... params) {
            return doAsync();
        }

        @Override
        protected void onPostExecute(T t) {
            if(daoProcessCallback != null)
                daoProcessCallback.onResult(t);
        }
    }
}

现在查询

fun putAllUsersAsync(vararg users: User) {
            object : DaoAsyncProcessor<Unit>(null) {
                override fun doAsync(): Unit {
                    yourDao.insertAll(*users)
                }

            }.start()
        }

又一个抓取数据的例子。

fun getAllUsers(callback: DaoAsyncProcessor.DaoProcessCallback<List<User>>) {
            object : DaoAsyncProcessor<List<User>>(callback) {
                override fun doAsync(): List<User> {
                    return yourDao.getAll()
                }

            }.start()

您可以调用 getAllUsers 并传递回调以获取数据。

根据要求,这是 Kotlin 的等价物

abstract class DaoAsyncProcessor<T>(val daoProcessCallback: DaoProcessCallback<T>?) {

    interface DaoProcessCallback<T> {
        fun onResult(result: T)
    }


    protected abstract fun doAsync(): T

    fun start() {
        DaoProcessAsyncTask().execute()
    }

    private inner class DaoProcessAsyncTask : AsyncTask<Void, Void, T>() {

        override fun doInBackground(vararg params: Void): T {
            return doAsync()
        }

        override fun onPostExecute(t: T) {
            daoProcessCallback?.onResult(t)
        }
    }
}

使用 RX java,您可以将 AsyncTask 替换为 insert/update/delete 命令的 Completable。

fun insert(sport: Sport) : Completable = Completable.fromAction { sportDAO.insert(sport) }
fun update(sport: Sport) : Completable = Completable.fromAction { sportDAO.update(sport) }
fun delete(sport: Sport) : Completable = Completable.fromAction { sportDAO.delete(sport) }

如果将实际执行所需的代码段传递给每个任务,则可以对每个任务使用相同的 AsyncTask。

例如,您可以使用 lambda-with-receivers 执行以下操作(无需添加 Rx completables/singles 或其他任何内容):

@Singleton
class SportRepository @Inject constructor(val sportDAO: SportDao) {
    companion object {
        const val LOG_TAG = "SportRepository"
    }

    var list: LiveData<List<Sport>> = sportDAO.getAll() // is this necessary?

    fun insert(sport: Sport) {
        executeTask(sport) { insert(it) }
    }

    fun update(sport: Sport){
        executeTask(sport) { update(it) }
    }

    fun delete(sport: Sport) {
        executeTask(sport) { delete(it) }
    }

    private fun executeTask(sport: Sport, task: SportDao.(Sport) -> Unit) {
        BackgroundTask(sport, task).execute()
    }

    @SuppressLint("StaticFieldLeak")
    private inner class BackgroundTask(
        private val sport: Sport,
        private val task: SportDao.(Sport) -> Unit
    ) : AsyncTask<Void, Void, Void>() {
        override fun doInBackground(vararg p0: Void): Void? {
            task(sportDAO, sport)
            return null
        }
    }
}