代码之家  ›  专栏  ›  技术社区  ›  Alexei

为此类型向gson注册instancecreator可能会解决此问题

  •  0
  • Alexei  · 技术社区  · 6 年前

    在我的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 回复  |  直到 6 年前
        1
  •  0
  •   Javatar    6 年前

    这是一个反序列化/序列化问题json<->对象。格森只能为你做这么多。

    您可以尝试对列表使用类型适配器。

    您还可以尝试创建一个使用instancecreator反序列化它的尝试,因为我必须对包含livedata的对象执行此操作。

    例子: https://futurestud.io/tutorials/gson-advanced-custom-instance-creator