在我的android应用中:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
private static Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(BuildConfig.API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(CoroutineCallAdapterFactory.Companion.create())
.client(httpClient.build());
public class Trader implements Serializable {
private String id;
private long last_iteration_time;
private double last_bnc_btx_diff_entrance_percent;
}
改造接口方法:
import kotlinx.coroutines.Deferred
import com.myproject.model.Trader
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Path
import retrofit2.http.Query
@GET("traders/json")
suspend fun getTraidersList(): Deferred<Response<List<Trader>>>
并使用它:
suspend fun getTraidersList(): TransportResponse = withContext(Dispatchers.IO) {
val traderMonitorRestClient = RestClientFactory.createRestClient(TraderMonitorRestClient::class.java)
val operrationDeferred: Deferred<Response<List<Trader>>> = traderMonitorRestClient.getTraidersList()
executeAwaitOperation(operrationDeferred)
}
private suspend fun executeAwaitOperation(operation: Deferred<Response<*>>): TransportResponse = withContext(Dispatchers.IO) {
...
}
但是抛出异常:
06-17 17:27:58.634 W/top (30820): type=1400 audit(0.0:139979963): avc: denied { search } for name="7" dev="proc" ino=9011 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:r:kernel:s0 tclass=dir permissive=0
06-17 17:27:58.982 E/AndroidRuntime(30688): FATAL EXCEPTION: main
06-17 17:27:58.982 E/AndroidRuntime(30688): Process: com.myproject.debug, PID: 30688
06-17 17:27:58.982 E/AndroidRuntime(30688): java.lang.RuntimeException: Unable to invoke no-args constructor for kotlinx.coroutines.Deferred<retrofit2.Response<java.util.List<com.myproject.model.Trader>>>. Registering an InstanceCreator with Gson for this type may fix this problem.
06-17 17:27:58.982 E/AndroidRuntime(30688): at com.google.gson.internal.ConstructorConstructor$14.construct(ConstructorConstructor.java:228)
06-17 17:27:58.982 E/AndroidRuntime(30688): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:212)
06-17 17:27:58.982 E/AndroidRuntime(30688): at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
06-17 17:27:58.982 E/AndroidRuntime(30688): at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
06-17 17:27:58.982 E/AndroidRuntime(30688): at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:225)
06-17 17:27:58.982 E/AndroidRuntime(30688): at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:121)
06-17 17:27:58.982 E/AndroidRuntime(30688): at okhttp3.RealCall$AsyncCall.execute(RealCall.java:206)
06-17 17:27:58.982 E/AndroidRuntime(30688): at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
06-17 17:27:58.982 E/AndroidRuntime(30688): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
06-17 17:27:58.982 E/AndroidRuntime(30688): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
06-17 17:27:58.982 E/AndroidRuntime(30688): at java.lang.Thread.run(Thread.java:818)
06-17 17:27:58.982 E/AndroidRuntime(30688): Caused by: java.lang.UnsupportedOperationException: Interface can't be instantiated! Interface name: kotlinx.coroutines.Deferred
06-17 17:27:58.982 E/AndroidRuntime(30688): at com.google.gson.internal.UnsafeAllocator.assertInstantiable(UnsafeAllocator.java:117)
06-17 17:27:58.982 E/AndroidRuntime(30688): at com.google.gson.internal.UnsafeAllocator$1.newInstance(UnsafeAllocator.java:49)
06-17 17:27:58.982 E/AndroidRuntime(30688): at com.google.gson.internal.ConstructorConstructor$14.construct(ConstructorConstructor.java:225)
06-17 17:27:58.982 E/AndroidRuntime(30688): ... 10 more
06-17 17:27:58.988 W/ActivityManager( 777): Force finishing activity com.myproject.debug/com.myproject.ui.activity.TradersActivity
答案 0 :(得分:8)
使用Deferred时,从Retrofit接口方法中删除暂停关键字。
答案 1 :(得分:3)
我有同样的问题。我从暂停函数调用接口中的函数,并且在接口中也将该函数称为暂停函数。解决方案是从界面的改装乐趣中删除暂停
例如:
之前:
interface ExampleInterface {
@POST("someContextPath")
suspend fun postFeedback(
@Body feedback: Feedback): Call<JsonObject>
}
之后:
interface ExampleInterface {
@POST("someContextPath")
fun postFeedback(
@Body feedback: Feedback): Call<JsonObject>
}
答案 2 :(得分:0)
这是反序列化/序列化问题JSON <->对象。吉森只能为您做这件事。
您可以尝试为列表使用TypeAdapter。
您还可以尝试创建一个使用InstanceCreator反序列化的尝试,就像我必须使用包含LiveData的对象一样。
示例: https://futurestud.io/tutorials/gson-advanced-custom-instance-creator