Đăng nhập Tài khoản VIP

Cặp đôi hoàn hảo Retrofit và Coroutines

Tương tác với Rest API trong ứng dụng Android thì Retrofit là một lựa chọn 9,5 điểm và trong bài viết này chúng ta hãy cùng xem Retrofit kết hợp với Coroutines (Kotlin) có gì thú vị.


Chúng ta cùng lần lượt lướt qua các trường hợp Retrofit kết hợp với Default, RxJava, Coroutines

Default

public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
} 


RxJava

public interface GitHubService {
  @GET("users/{user}/repos")
  fun listRepos(@Path("user") user: String): Single<List<Repo>>
} 


Coroutines

public interface GitHubService {
  @GET("users/{user}/repos")
  suspend fun listReposAsync1(@Path("user") user: String): List<Repo>

  @GET("users/{user}/repos")
  fun listReposAsync2(@Path("user") user: String): Deferred<List<Repo>>
} 


Nhìn vào 3 phần code này thì Coroutines có hai điểm mới SuspendDeferred với suspend keyword thì mình đã có một bài viết khá chi tiết về nó (Tìm hiểu Suspend Function) còn Deferred các bạn có thể coi nó như một background job có thể cancellable và chúng ta có thể lấy kết quả từ Deferred thông qua await().


Giờ hãy xem cách chúng ta sử dụng các API kết hợp với Coroutines.

launch {
    val response = withContext(Dispatchers.IO) {
        gitHubService.listRepos("thanhniencung")
    }
    Log.e("RETROFIT_CODE4FUNC", "${response.size}")
}

hoặc

launch {
    withContext(Dispatchers.IO) {
        Log.e("THREAD", Thread.currentThread().name)
        var res1 = gitHubService.listReposAsync2("thanhniencung")
        var res2 = gitHubService.listReposAsync2("thanhniencung")
        
        Log.e("RETROFIT_CODE4FUNC", "${res1.await().size + res2.await().size}")
    }
}

Cảm ơn Coroutines, nhờ thằng bạn mà mình không còn phải làm việc với callback nữa. Code vẫn như bình thường mà vẫn đảm bảo tính Async cho ứng dụng.


Hãy xem cách Retrofit default, RxJava call api

gitHubService.listRepos("thanhniencung").enqueue(object: Callback<List<Repo>> {
    override fun onResponse(call: Call<List<Repo>>, response: Response<List<Repo>>) {
        TODO("Not yet implemented")
    }

    override fun onFailure(call: Call<List<Repo>>, t: Throwable) {
        TODO("Not yet implemented")
    }
})


gitHubService.listRepos("thanhniencung")
    .observeOn(AndroidSchedulers.mainThread())
    .subscribeOn(Schedulers.io())
    .subscribe(object: SingleObserver<List<Repo>> {
        override fun onSuccess(t: List<Repo>) {
            TODO("Not yet implemented")
        }

        override fun onError(e: Throwable) {
            TODO("Not yet implemented")
        }

        override fun onSubscribe(d: Disposable) {
            TODO("Not yet implemented")
        }
    })

Có lẽ mình là một người có mới nỡi cũ, nhưng mình đã cố gắng mà không thể yêu hai cách này được, yêu Coroutines cơ 😅


Chốt lại Kotlin là sự lựa chọn >= Java khi làm ứng dụng Android. Tất nhiên nếu Team của bạn không có thời gian học + nghiên cứu thì vẫn cầm cự với Java không sao cả còn nếu bạn muốn tạo ra một luồng gió mới cho Team, ứng dụng của mình thì nhớ chốt Kotlin nhé.