in short : I want to create a generic class of Type T
that should be calling a reified inline function of type T
to be able to use Gson more generically
in details:
Hello. I had recently started using kotlin for Android dev, and i was trying to create a generic network client class. The class would fetch the data from server, convert the response into a datatype provided by the generic class's type and return the response, something like this:
class GenericNetworkService<RESPONSE_TYPE> {
fun getDataFromServer(url: String): RESPONSE_TYPE {
val request = Request.Builder().url(url).build()
val response = OkHttpClient().newCall(request).execute()
val convertor = Gson()
val result: RESPONSE_TYPE = convertor.fromJson(response.body!!.string(), RESPONSE_TYPE)
return result
}
}
//calling
//fun main() {
// val listOfPersons = GenericNetworkService<List<Person>>().getDataFromServer(url1)
// println(listOfPersons)
// val listOFTeacher = GenericNetworkService<List<Teacher>>().getDataFromServer(url2)
// println(listOFTeacher)
// }
here , only the gson.fromJson()
func is the one which is actually needing the details of the class in which the final output has to be converted . But it doesn't takes the generic type into second parameter, so the above program would not work.
After searching through some internet articles, i came across thisTypeToken
Api which helps achieve generic behavior upto certain extent:
inline fun <reified T> fromJson(json: String): T {
return Gson().fromJson(json, object: TypeToken<T>(){}.type)
}
//calling :
// val data : List<Teacher> = fromJson(response)
using inline reified functions, i am able to achieve everything i originally want:
private inline fun <reified RESPONSE_TYPE> getGenericRespSync(url: String): RESPONSE_TYPE {
val okHttpClient = generateNetworkClient()
val request = Request.Builder().url(url).build()
val response: Response = okHttpClient.newCall(request).execute()
val body: Reader = response.body!!.charStream()
val finalResponse: RESPONSE_TYPE = getConvertedListForResponse(body) //this is the same reified inline function as above with some non signinficant additions
return finalResponse
}
But i want my other classes to call this function via some class instance. i.e something like GenericNetworkService<List<Person>>().getGenericRespSync(url1)
should be returning List and not the direct call to getGenericRespSync(url1)
. How can i achieve such functionality?