Hey there! I'm looking for feedback. I'm trying to...
# coroutines
p
Hey there! I'm looking for feedback. I'm trying to implement
NetworkBoundResource
with Coroutines (instead of
Executor
like the Google sample https://github.com/googlesamples/android-architecture-components/blob/master/GithubBrowserSample/app/src/main/java/com/android/example/github/repository/NetworkBoundResource.kt). I also want that
NetworkBoundResource
return a
LiveData
through the method
asLiveData()
. 1️⃣ My first try was to pass a
CoroutineScope
to the constructor of
NetworkBoundResource
, to properly manage cancellation. Pros: in this way, tasks are canceled when a ViewModel is cleared for example. Cons: My
UserRepository
methods ask for parameter a
CoroutineScope
for each call 🔗 https://gist.github.com/PhilippeBoisney/47b9eaee02df537cf7b0703707243a78 2️⃣ My second try was to use a
GlobalScope
to launch the Coroutines inside the
NetworkBoundResource
. Pros: No more
CoroutineScope
passed through `UserRepository`methods parameters. Cons:
GlobalScope
should be avoided (even if in Google sample, they use
Executor
the same way of a
GlobalScope
) 🔗 https://gist.github.com/PhilippeBoisney/4a5fc718a2b8d9735bdf2a5bfb37aebe Which one of those approaches do you prefer? If none, how will you do? 🧵
1️⃣ 6
2️⃣ 1
🧵 1
s
3️⃣ Declare the methods of the UserRepository to be extension-functions of
CoroutineScope
. 4️⃣ Declare the methods of the UserRepository to be
suspend
4️⃣ 1
d
Have the repository emit it’s state via an Event to a EventBus that gets picked up by a reducer which in turn emits its new ViewState to the EventBus to be picked up by the StateHolder (A.K.A. ViewModel).
No more of the problems you are describing exist.
j
What I did was to have the logic of Network bound resource inside a suspended function within my base repo which accepts network/db calls as a suspended lambdas and run it on the scope of the calling function, which would be lets say for ex, from the user repo. All the exceptions and error handling/catching can be done in the BaseRepo and it returns a Resource<Result, Error> type back to the caller which can propagate back as either a livedata of the result incase if you want to have db data while waiting for remote etc or directly as the result. I'm still in the process of simplifying this and making the suspensions efficient as possible. There is no CoroutineScope passed around as the coroutine builders exist only in the VM and there on its only suspending functions from the repo down to room and retrofit. With the alpha lifecycle-viewmodel extension, you can get the viewmodelScope within your VM which handles cancellation of the coroutines when onCleared gets called etc..
So you wouldn't need to create instance of the network bound resource every time and implement the methods which in my opinion is ugly to look at. Lamdas makes it look much nicer.
Copy code
val result = loadData<ResponseBody, LogoutError> {
            apiInterface.logout()
        }
I can pass in a db call lambda if i need to get cached data from the db.
A prototype version of this can be found here- https://gist.github.com/jishindev/fc947721b07a4700ff192e1fe80c0fc7