Я использую CoroutineWorker, чтобы взять некоторые данные из базы данных комнаты и отправить их на сервер, а затем снова удалить этот конкретный ответ из базы данных. Я использую шаблон репозитория.
class SendLocalAnswerToServer(ctx: Context, val params: WorkerParameters) :
CoroutineWorker(ctx, params) {
var useCaseHandler: UseCaseHandler? = null
var deleteAnswerFromTable: DeleteAnswerFromTable? = null
private var uploadAutoSavedAnswer: UploadAutoSavedAnswer? = null
val TAG:String= "SendLocalAnswerToServer"
override suspend fun doWork(): Result = runBlocking {
val questionID = params.inputData.getLong("questionID", 0)
val answerDao = UserDatabase.getDatabase(App.getInstance()).answerDao()
val answerAPIRepo = NetWorkUtil.provideRetrofit().create(AnswerAPI::class.java)
uploadAutoSavedAnswer = UploadAutoSavedAnswer(this, answerDao, answerAPIRepo)
deleteAnswerFromTable = DeleteAnswerFromTable(this, answerDao)
useCaseHandler = InjectionUtils.provideUseCaseHandler()
val requestValues = UploadAutoSavedAnswer.RequestValues()
requestValues.questionID = questionID
Log.e(TAG, " Main 1")
launch {
useCaseHandler!!.execute(uploadAutoSavedAnswer!!, requestValues,
object :
UseCase.UseCaseCallback<UploadAutoSavedAnswer.ResponseValues> {
override fun onSuccess(response: UploadAutoSavedAnswer.ResponseValues) {
Log.e(TAG, " onSuccess 1")
response.observable?.subscribeOn(Schedulers.io())?.observeOn(
AndroidSchedulers.mainThread())!!.subscribeWith(
object :
DisposableObserver<UserAnswerResponseModel>() {
override fun onComplete() {
}
override fun onNext(t: UserAnswerResponseModel) {
Log.e("TAG", " onNext ")
val requestValues = DeleteAnswerFromTable.RequestValues()
requestValues.answerID = t.question.id!!
useCaseHandler?.execute(
deleteAnswerFromTable!!,
requestValues,
object :
UseCase.UseCaseCallback<DeleteAnswerFromTable.ResponseValues> {
override fun onSuccess(
response: DeleteAnswerFromTable.ResponseValues) {
Log.e("TAG", " onSuccess 2")
// I want to return Result.Success() from here
}
override fun onError(
throwable: Throwable) {
// I want to return Result.Error() from here
}
})
}
override fun onError(e: Throwable) {
}
})
}
override fun onError(throwable: Throwable) {
}
})
}
Log.e(TAG, " MAIN 2")
Result.success()
}
}
Вывод печатает
E/SendLocalAnswerToServer: Main 1
E/SendLocalAnswerToServer: MAIN 2
Как я могу вернуть значение из последнего метода успеха или возврата, прямо сейчас оно переходит в первую функцию useCaseHandler!!.execute(), которая далее запускает новый поток, поэтому сопрограммы просто возвращают оттуда любое решение, такое, что когда весь вызов API и дальнейшее удаление из таблицы было выполнено, тогда только он должен вернуть успех
Когда вы используете useCaseHandler.execute(...)
, в каком потоке он выполняет запрос? Проблема в том, что вы на самом деле вообще не используете сопрограммы. Вы смешиваете API на основе обратных вызовов и API на основе Rx (неправильно).
У вас есть 2 варианта. Либо используйте сопрограммы правильно, либо используйте CountDownLatch
.
это сочетание обоих useCaseHandler.execute(...) запускает новый поток, потому что, а затем я определяю разные сопрограммы для запроса к базе данных, а затем публикую данные, полученные из базы данных, на сервер с помощью RxJava, так что это сочетание обоих, может вы даете мне больше информации о том, как реструктурировать его. Первоначально я использовал обратный отсчет и запуск, но когда оба комбайна, внутренние методы не вызывались, но после удаления запуска это сработало, спасибо за это.