0

My Android Application is base on a TCP protocol.

When I'm initializing a connection to the server, I'm sending a special bytes message and have to wait the response of the server.

In all the repositories example I have seen the repository have always methods to call the source of information with a return (from Android Developers) :

class UserRepository {
   private val webservice: Webservice = TODO()
   // ...
   fun getUser(userId: String): LiveData<User> {
       // This isn't an optimal implementation. We'll fix it later.
       val data = MutableLiveData<User>()
       webservice.getUser(userId).enqueue(object : Callback<User> {
           override fun onResponse(call: Call<User>, response: Response<User>) {
               data.value = response.body()
           }
           // Error case is left out for brevity.
           override fun onFailure(call: Call<User>, t: Throwable) {
               TODO()
           }
       })
       return data
   }
}

The function getUser return a data of LiveData. In my app the method Login return nothing because I wait for the server to send bytes with a special code to know that is responding to my login request.

Is there a way to implement this pattern with TCP protocols like that ?

Thanks

Sercurio
  • 70
  • 7
  • `The function getUser return a data of LiveData`. It looks like that. But does it return a user? – blackapps Aug 04 '20 at 08:12
  • `I'm sending a special bytes message and have to wait the response of the server.` Yes, but as you do that in a thread you can meanwhile do all other kind of things. And once the response is received the thread can call runOnUiThread. So there is all you need. – blackapps Aug 04 '20 at 08:15
  • For the moment, when I receive a response in my thread I use interface to get the data in my UI thread and update the UI. But I'm not using LiveData and that the aim using the repository pattern – Sercurio Aug 04 '20 at 08:22

1 Answers1

0

They honestly should have just written the following code:

class UserRepository {
   private val webService: WebService = TODO()
   // ...
   fun getUser(userId: String, successCallback: (User) -> Unit) {
       webService.getUser(userId).enqueue(object : Callback<User> {
           override fun onResponse(call: Call<User>, response: Response<User>) {
               successCallback(response.body())
           }

           // Error case is left out for brevity.
           override fun onFailure(call: Call<User>, t: Throwable) {
           }
       })
   }
}

LiveData is not meant to represent one-off callbacks.


Then call it as

userRepository.getUser(userId) { user ->
    // do whatever
}

For a proper reactive implementation, refer to https://stackoverflow.com/a/59109512/2413303

EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
  • Thanks buddy, let me the time to understand this big brain answer and will mark this as accepted – Sercurio Aug 13 '20 at 14:27
  • Sorry buddy, but I don't understand how to implement it in my code. I have a function sendLogin that write to the socket's OutputStream and return nothing. Later when reading the socket InputStream, it will trigger a function in the same class named receiveLogin, but I don't know how link them because it's asynchronous. – Sercurio Aug 17 '20 at 14:21