Skip to content
This repository was archived by the owner on Aug 9, 2020. It is now read-only.
This repository was archived by the owner on Aug 9, 2020. It is now read-only.

java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap  #41

Closed
@androidle

Description

@androidle

i use retrofit + rxjava + rxcache in my project,and the response json data format is:

{"data":{},"status":200}

i define a BaseResponse.class ps : data is a object not list:

public class BaseResponse<T> { public int status; public T data; }

i define a cache interface method :
@LifeCache(duration = 20, timeUnit = TimeUnit.MINUTES) Observable<Reply<BaseResponse<UserBasicInfoResponse>>> loadUserBasicInfo(Observable<BaseResponse<UserBasicInfoResponse>> userBasicInfoResponseObservable , DynamicKey userId , EvictProvider evictProvider);

when racache load from memory it's ok,but raCache load from disk an error has occurred(java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap ),I don't know how to solve this question.

when i debug I find diskCache lose type "UserBasicInfoResponse", do you have any advice about it ?

thinks!

Activity

VictorAlbertos

VictorAlbertos commented on Jun 22, 2016

@VictorAlbertos
Owner

Don't save the object BaseResponse, instead, use map operator to transform it to UserBasicInfoResponse prior to calling RxCache.

 Observable<UserBasicInfoResponse> oUser = userBasicInfoResponseObservable
     .map(userBasicInfoResponse -> userBasicInfoResponse.data);

rxProviders.loadUserBasicInfo(oUser , new DynamicKey(1) , new EvictProvider(false));
androidle

androidle commented on Jun 22, 2016

@androidle
Author

Thinks so much for your quick reply!
but I still have some confused ,since data from net is Observable<BaseResponse<UserBasicInfoResponse>>,how can I save UserBasicInfoResponse instead of BaseResponse<UserBasicInfoResponse> , do you give me some detail advices ?
thanks!

my core code about it as below
This is the core method:

 @Override
    public Observable<UserBasicInfo> getUserBasicInfo(final boolean isUpdateNow) {

        return mLoginUserCache.get()
                .flatMap(new Func1<User, Observable<Reply<BaseResponse<UserBasicInfoResponse>>>>() {
                    @Override
                    public Observable<Reply<BaseResponse<UserBasicInfoResponse>>> call(User user) {
                        return mUserCacheProviders.loadUserBasicInfo(mUserApi.loadUserBasicInfo(user.getUserId()), new DynamicKey(user.getUserId()), new EvictProvider(isUpdateNow));
                    }
                }).flatMap(new Func1<Reply<BaseResponse<UserBasicInfoResponse>>, Observable<UserBasicInfo>>() {
                    @Override
                    public Observable<UserBasicInfo> call(Reply<BaseResponse<UserBasicInfoResponse>> baseResponseReply) {
                        if (null == baseResponseReply || null == baseResponseReply.getData()) {
                            return Observable.empty();
                        }
                        BaseResponse<UserBasicInfoResponse> userBasicInfoResponseBaseResponse = baseResponseReply.getData();
                        if (!userBasicInfoResponseBaseResponse.isSuccess()) {
                            return Observable.error(new ServerResponseException(userBasicInfoResponseBaseResponse.getMsg()));
                        }
                        ThinkcooLog.d("---->", userBasicInfoResponseBaseResponse.toString());
                        UserBasicInfoResponse userBasicInfoResponse = userBasicInfoResponseBaseResponse.getData();
                        return Observable.just(UserBasicInfo.fromServerResponse(userBasicInfoResponse, mServerDataConverter));
                    }
                });

    }

This is the net API

 @POST("personalinfor.json")
Observable<BaseResponse<UserBasicInfoResponse>> loadUserBasicInfo(@Query("userId") String userId);

This is the cache interface method

@LifeCache(duration =5, timeUnit = TimeUnit.SECONDS)
    Observable<Reply<BaseResponse<UserBasicInfoResponse>>> loadUserBasicInfo(Observable<BaseResponse<UserBasicInfoResponse>> userBasicInfoResponseObservable
            , DynamicKey userId , EvictProvider evictProvider);
VictorAlbertos

VictorAlbertos commented on Jun 22, 2016

@VictorAlbertos
Owner

The endpoint should be

@LifeCache(duration =5, timeUnit = TimeUnit.SECONDS)
    Observable<UserBasicInfoResponse> loadUserBasicInfo(Observable<UserBasicInfoResponse> userBasicInfoResponseObservable
            , DynamicKey userId , EvictProvider evictProvider);

And you just need to apply the map operator to transform the data. I suggest to you to learn a little more rxjava before attempting to use RxCache, or any reactive library for that matters. ;)

androidle

androidle commented on Jun 23, 2016

@androidle
Author

OK,thank you so much!

guobinAndroid

guobinAndroid commented on Dec 23, 2016

@guobinAndroid

but if i want to save just baseResponse, how can i do @VictorAlbertos

ml-bright

ml-bright commented on Dec 24, 2016

@ml-bright

this is my method to avoid use BaseResponse<T>

@VictorAlbertos help me that whether this can sovle problem

#73

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @VictorAlbertos@ml-bright@androidle@guobinAndroid

        Issue actions

          java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap · Issue #41 · VictorAlbertos/RxCache