CompletableFuture<T> freezes UI

129 Views Asked by At

I am currently working on an api for my client application which needs to process http requests (using unirest) asynchronously as of now. I am new to CompletableFuture and haven't worked with anything similar up to this point. I was wondering whether the following structure makes sense:

// Request.kt (simplified)

class Request<T>(
   // other variables relevant to the request such as body or path ...
   private val responseType: Class<T>
) {

  fun prepareRequest(action: (HttpRequest<*>) -> U): U {
     // preprocesses the request, adds body if necessary and returns the request itself
  }

  fun executeAsync(action: (HttpResponse<T>) -> Unit) {
     prepareRequest { req ->
        action(req.asObjectAsync(responseType).get()) // Unirest call that (still) freezes the UI
     }
  }

  // Builder logic ...
}

// ApiClient.kt (simplified)

abstract class ApiClient {

   protected fun <T> executeAsync(req: Request<T>, action: (T) -> Unit) {
      req.executeAsync { res ->
         if (res.isSuccess){
            action(res.body)
         } else {
            throw RuntimeException("res != 200")
         }
      }
   }
}

// AuthClient.kt (simplified)

class AuthClient : ApiClient() {

   fun signin(email: String, password: String, onSuccess: () -> Unit) {
      executeAsync(
         Request.builder(TokenModel::class.java)
            .post("/signin")
            .body(SignInModel(email, password))
            .build()
      ) {
         onSuccess() // this is going to refresh the UI, once the http request has been executed
      }
   }
}

As the call to get on CompletableFuture freezes the UI I thought of including an Executor or a Thread instead so that executeAsync in Request becomes the following:

fun executeAsync(action: (HttpResponse<T>) -> Unit) {
   prepareRequest { req ->
      Executors.newSingleThreadScheduledExecutor().execute {
         action(it.asObjectAsync(responseType).get())
      }
   }
}

Is my structure overly complex or does it have to be like that? Do I need the Thread/Executor or can this be achieved in a different way?

0

There are 0 best solutions below