Возможно, это очень простая тема, но я не могу найти правильный ответ.
Это сделка, я использовал эту логику для обработки API в моем текущем проекте Android:
класс SampleApi
интерфейс ISampleApi
интерфейс SampleClient
класс GetUserData
Теперь, когда я переезжаю в Котлин, я не могу скопировать функцию enqueue()
из модернизации в мой класс Api.Это пример моего кода:
GetUserData.java:
class GetUserData {
private void tryGetData() {
sampleApi.getSomeData(userId, new Callback<Data>() {
@Override
public void onResponse(final Call<Data> call, final Response<Data> response) {
......Do Something
}
@Override
public void onFailure(final Call<Data> call, final Throwable t) {
......Do Something
}
});
Я использую интерфейс для объявления методов, которые будут реализованы в классе API:
public interface ISampleApi {
void getSomeData(@NonNull String userId,
@NonNull Callback<Data> callback);
}
Это мой класс API:
public class SampleApi implements ISampleApi {
............
@Override
public void getSomeData(@NonNull final String userId,
@NonNull final Callback<Data> callback) {
myClient.getSomeData(userId).enqueue(callback);
}
}
А это MyClient с использованием Retrofit:
public interface SampleClient {
@GET("user/data/{userId}")
Call<Data> getSomeData(@NonNull @Path("userId") String userId);
}
Весь код выше работает нормально, это то, что я используюв моем приложении без проблем.
Теперь, это проблема при переходе на Kotlin, я пытаюсь создать обратный вызов enqueue в SampleApi, и мне нужно вернуть ответ классу, где был создан обратный вызов,в Kotlin должно быть что-то вроде этого:
fun getSomeData(userId: String, callback: CallBack<Data>) {
client?.getSomeData(userId).enqueue(callback)
}
Но при попытке сделать это, Android Studio говорит мне, что я должен создать функцию расширения, я создаю функцию расширения, и после большего предложения от Android Studioи некоторые исследования показывают, что результат выглядит примерно так:
override fun getSomeData(@NonNull userId: String,
@NonNull callback: Callback<Data>) {//Neve using this callback
client?.getSomeData(userId).enqueue {
success = {
success -> Do Something
}
failure = {
failure -> Do Something
}
}
}
fun<T> Call<T>.enqueue(callback: BaseCallback<T>.() -> Unit) {
val callbackBk = BaseCallback<T>()
callback.invoke(callbackBk)
this.enqueue(callbackBk)
}
class BaseCallback<T>: Callback<T> {
var success: ((Response<T>) -> Unit)? = null
var failure: ((t: Throwable?) -> Unit)? = null
override fun onFailure(call: Call<T>, t: Throwable) {
failure?.invoke(t)
}
override fun onResponse(call: Call<T>, response: Response<T>) {
success?.invoke(response)
}
}
BaseCallback.kt
open class BaseCallback<T: Validatable>(): Callback<BaseResponseBody<T>> {
var success: ((T) -> Unit)? = null
var failure: ((networkingError: NetworkingError?) -> Unit)? = null
override fun onResponse(call: Call<BaseResponseBody<T>>, response: Response<BaseResponseBody<T>>) {
if (response?.code() != null
&& response.isSuccessful
&& response.body() != null
&& response.body().containsValidSuccess()) run {
onSuccessfulResponse(response.body().data!!)
} else if (response != null
&& response.isSuccessful
&& response.body() != null) {
onSuccessfulResponse()
} else {
onNonSessionErrorEncountered(networkingError)
}
}
override fun onFailure(call: Call<BaseResponseBody<T>>, throwable: Throwable) {
onNonSessionErrorEncountered(NetworkStateError(throwable))
}
@VisibleForTesting(otherwise = PROTECTED)
fun onSuccessfulResponse(responseValue: T) {
success?.invoke(responseValue)
}
@VisibleForTesting(otherwise = PROTECTED)
fun onSuccessfulResponse() {
// This method intentionally left blank.
}
fun onSessionErrorEncountered() {
// This method intentionally left blank.
}
@VisibleForTesting(otherwise = PROTECTED)
fun onNonSessionErrorEncountered(networkingError: NetworkingError) {
failure?.invoke(networkingError)
}
}
Этот код работает нормально, я могу получать данные, но мне нужно получить ответвнутри классакоторый вызывает эту конечную точку, так как мне нужно изменить пользовательский интерфейс.
Я очень ценю некоторую помощь, я застрял с этим некоторое время, и мне нужно решить проблему, чтобы продолжить работу с приложением.