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

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

Closed
androidle opened this issue Jun 22, 2016 · 6 comments
Closed

Comments

@androidle
Copy link

androidle commented Jun 22, 2016

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!

@VictorAlbertos
Copy link
Owner

VictorAlbertos commented Jun 22, 2016

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
Copy link
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
Copy link
Owner

VictorAlbertos commented Jun 22, 2016

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
Copy link
Author

OK,thank you so much!

@guobinAndroid
Copy link

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

@ml-bright
Copy link

this is my method to avoid use BaseResponse<T>

@VictorAlbertos help me that whether this can sovle problem

#73

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants