Android Java/Kotlin - Get all annotated parameters in method and convert to HashMap

Viewed 452

This question is about custom annotation in Android development (Java/Kotlin). I want to create custom annotation for methods and their parameters, then create a HashMap from annotation keys and parameter values. My app is currently using ParseCloud as network library. A typical ParseCloud API request looks like:

ParseCloud.callFunctionInBackground(String, Map<String, Object>, FunctionCallback<T>)

For example, if I want to perform a login request, I will have to write (Kotlin):

fun login(username: String, password: String) {
    val params = HashMap<String, Any>()
    params["username"] = username
    params["password"] = password
    val callback = ... //FunctionCallback<LoginResponse>, LoginResponse is response data class
    ParseCloud.callFunctionInBackground("apiLogin", params, callback)
}

If using Retrofit we can easily write:

@FormUrlEncoded
@POST("apiLogin")
fun login(@Field("username") username: String,
          @Field("password") password: String) : Call<LoginResponse>

I like Retrofit API declaration style and want to make the same thing, so I started writing:

// Annotation ApiParam, used for variables and parameters
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD, AnnotationTarget.LOCAL_VARIABLE, AnnotationTarget.VALUE_PARAMETER)
annotation class ApiParam(val key: String = "")

// Annotation ApiMethod, used for methods
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class ApiMethod(val api: String)

// Class ApiRequest that holds API path, parameters and method to send request
class ApiRequest<T>(private val api: String, private var params: Map<String, Any>) {
    fun send(callback: FunctionCallback<in T>) {
        ParseCloud.callFunctionInBackground(api, params, callback)
    }
}

So what I should do to achieve something like:

interface AuthApiService {
    @ApiMethod("apiLogin")
    fun login(@ApiParam("username") username: String,
              @ApiParam("password") password: String): ApiRequest<LoginResponse>
}

and then:

fun login(username: String, password: String) {
    val api = ... // Create an instance of interface AuthApiService, it's also a great challenge
    val callback = ... // FunctionCallback<LoginResponse>
    api.login(username, password).send(callback)
}

Thank you.

0 Answers
Related