androidkotlinretrofit2kotlin-inline-class

I am not sure how to optimize retrofit with callback in kotlin, or how to remove the callback after its done


I am using callbacks in Kotlin, and I currently have the exact retrofit function returning result in the form of a callback as its used multiple times across different classes,the endpoints are different, but the calling structure is always the same

RetrofitInstance().UserAction("retrieveChatForUser",cuserData){ returnMessage->
            if(returnMessage.status==true) {
                val chatList = returnMessage.content as List<Any>
                adapter.setData(chatList)
            }
        }

and my common retrofit class it like this

class RetrofitInstance {

 fun UserAction(action:String, userData: UserData, toUserData: UserData?=null, returnCallback:(ReturnMessage)->Unit){
    val retrofit = Retrofit.Builder()
        .baseUrl(CommonVals.base_url)
        .addConverterFactory(GsonConverterFactory.create())
        .build()
    val service: RestApiUser = retrofit.create(RestApiUser::class.java)
    val callAuth: Call<ReturnMessage> = service.authOraddUser(action, userData.username,userData.phonenumber,toUserData?.username)
    callAuth.enqueue(object : Callback<ReturnMessage> {
        override fun onResponse(call: Call<ReturnMessage>, response: Response<ReturnMessage>) {
            if (response.isSuccessful) {
                val post = response.body()
                post?.let { post->
                    Log.d("api","${action} ${post}")
                    returnCallback(post)
                }
            } else {
                Log.d("apierror", "${action} error ${response.code()}")
            }
        }
        override fun onFailure(call: Call<ReturnMessage>, t: Throwable) {
            Log.d("apierror","${action} error ${t.message}")
        }
    })
}

private interface RestApiUser {
    @FormUrlEncoded
    @POST("{action}")
    fun authOraddUser(
        @Path("action") action:String,
        @Field("username") username: String?=null,
        @Field("password") password: String?=null,
        @Field("username2") username2: String?=null,
    ): Call<ReturnMessage>
}

}

I am currently not sure if the callbacks will be immediately removed after execution; if so I am not sure how to remove them after I receive the callback, as I want to make the class as an object so that I don't create multiple objects instances


Solution

  • You should not implement retrofit this way. you can try this way the first. let's create interface, let's say you have 2 different types of api

    // Api user
    public interface RestApiUser {
        @FormUrlEncoded
        @POST("{action}")
        fun authOraddUser(
            @Path("action") action: String,
            @Field("username") username: String? = null,
            @Field("password") password: String? = null,
            @Field("username2") username2: String? = null,
        ): Call<ReturnMessage>
    
        @POST("{logout}")
        fun logout(): Call<ReturnMessage>
    }
    //api chatting
    public  interface RestApiChatting {
        @POST("{chatting}")
        fun chatting(
            @Path("chatting") action: String,
        ): Call<ReturnMessage>
    }
    

    After that, create a class to manage it

    object ApiManager {
    
        val ApiUser = Retrofit.Builder()
            .baseUrl("https://api.abc/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(RestApiUser::class.java)
    
    
        val ApiProfile = Retrofit.Builder()
            .baseUrl("https://api.abc/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(RestApiChatting::class.java)
    }
    

    use it

    fun userAction(
        action: String,
        userData: UserData,
        toUserData: UserData? = null,
        returnCallback: (ReturnMessage) -> Unit
    ) {
        val callAuth: Call<ReturnMessage> =
            ApiManager.ApiUser.authOraddUser(
                action,
                userData.username,
                userData.phonenumber,
                toUserData?.username
            )
        callAuth.enqueue(object : Callback<ReturnMessage> {
            override fun onResponse(call: Call<ReturnMessage>, response: Response<ReturnMessage>) {
              returnCallback()
            }
    
            override fun onFailure(call: Call<ReturnMessage>, t: Throwable) {
    
            }
        })
    }
    

    This approach will ensure that only 1 object is created in the entire program. it will not create multiple object instances