f2prateek / rx-preferences

Reactive SharedPreferences for Android
http://f2prateek.com/2015/10/05/rx-preferences/
Apache License 2.0
1.54k stars 132 forks source link

Please add demo for store object in prefrences using Preference.Converter it is giving exception ? #103

Closed maheshordex closed 6 years ago

maheshordex commented 7 years ago
E/EventBus: Could not dispatch event: class com.app.tpk.pojo.User to subscribing class class com.app.tpk.fragment.SignInFragment
                                                          java.lang.NullPointerException: Serialized string must not be null from value: com.app.tpk.pojo.User@ddde641
                                                              at com.f2prateek.rx.preferences2.Preconditions.checkNotNull(Preconditions.java:6)
                                                              at com.f2prateek.rx.preferences2.ConverterAdapter.set(ConverterAdapter.java:26)
                                                              at com.f2prateek.rx.preferences2.RealPreference.set(RealPreference.java:72)
                                                              at com.app.tpk.fragment.SignInFragment.onEvent(SignInFragment.java:186)
                                                              at java.lang.reflect.Method.invoke(Native Method)
                                                              at java.lang.reflect.Method.invoke(Method.java:372)
                                                              at org.greenrobot.eventbus.EventBus.invokeSubscriber(EventBus.java:485)
                                                              at org.greenrobot.eventbus.EventBus.postToSubscription(EventBus.java:416)
                                                              at org.greenrobot.eventbus.EventBus.postSingleEventForEventType(EventBus.java:397)
                                                              at org.greenrobot.eventbus.EventBus.postSingleEvent(EventBus.java:370)
                                                              at org.greenrobot.eventbus.EventBus.post(EventBus.java:251)
                                                              at com.app.tpk.net.tpkApi.lambda$login$3(tpkApi.java:163)
                                                              at com.app.tpk.net.tpkApi$$Lambda$4.accept(Unknown Source)
                                                              at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:60)
                                                              at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:200)
                                                              at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:252)
                                                              at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:109)
                                                              at android.os.Handler.handleCallback(Handler.java:739)
                                                              at android.os.Handler.dispatchMessage(Handler.java:95)
                                                              at android.os.Looper.loop(Looper.java:135)
                                                              at android.app.ActivityThread.main(ActivityThread.java:5343)
                                                              at java.lang.reflect.Method.invoke(Native Method)
                                                              at java.lang.reflect.Method.invoke(Method.java:372)
                                                              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
                                                              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)

User.java

@Getter
 @Setter
public class User{

    @SerializedName("hmProfileCompletionStatus")
    @Expose
    private int hmProfileCompletionStatus;
    @SerializedName("poProfileCompletionStatus")
    @Expose
    private int poProfileCompletionStatus;

    @SerializedName("custStripeToken")
    @Expose
    private String custStripeToken;

    @SerializedName("bgcStatus")
    @Expose
    private boolean bgcStatus;
    @SerializedName("idCardStatus")
    @Expose
    private boolean idCardStatus;
    @SerializedName("isInsured")
    @Expose
    private String isInsured;
    @SerializedName("amISponsered")
    @Expose
    private boolean amISponsered;
    @SerializedName("hmRating")
    @Expose
    private String hmRating;
    @SerializedName("poRating")
    @Expose
    private String poRating;

    @SerializedName("userId")
    @Expose
    private int userId;
    @SerializedName("userName")
    @Expose
    private String userName;
    @SerializedName("password")
    @Expose
    private String password;
    @SerializedName("newPassword")
    @Expose
    private String newPassword;
    @SerializedName("firstName")
    @Expose
    private String firstName;
    @SerializedName("lastName")
    @Expose
    private String lastName;
    @SerializedName("isPo")
    @Expose
    private String isPo;
    @SerializedName("isHm")
    @Expose
    private String isHm;
    @SerializedName("isBo")
    @Expose
    private String isBo;
    @SerializedName("email")
    @Expose
    private String email;
    @SerializedName("businessName")
    @Expose
    private String businessName;
    @SerializedName("dob")
    @Expose
    private String dob;
    @SerializedName("mobile")
    @Expose
    private String mobile;
    @SerializedName("address1")
    @Expose
    private String address1;
    @SerializedName("address2")
    @Expose
    private String address2;
    @SerializedName("city")
    @Expose
    private String city;
    @SerializedName("state")
    @Expose
    private String state;
    @SerializedName("zip")
    @Expose
    private String zip;
    @SerializedName("country")
    @Expose
    private String country;
    @SerializedName("isFbSignIn")
    @Expose
    private boolean isFbSignIn;
    @SerializedName("isTwitterSignIn")
    @Expose
    private boolean isTwitterSignIn;
    @SerializedName("fbAppId")
    @Expose
    private String fbAppId;
    @SerializedName("twitterAppId")
    @Expose
    private String twitterAppId;
    @SerializedName("picture")
    @Expose
    private String picture;
    @SerializedName("longitude")
    @Expose
    private String longitude;
    @SerializedName("latitude")
    @Expose
    private String latitude;
    @SerializedName("isPrimaryAddress")
    @Expose
    private String isPrimaryAddress;
    @SerializedName("isDefaultAddress")
    @Expose
    private String isDefaultAddress;
    @SerializedName("propertyName")
    @Expose
    private String propertyName;
    @SerializedName("hmPhoto")
    @Expose
    private String hmPhoto;
    @SerializedName("poPhoto")
    @Expose
    private String poPhoto;
    @SerializedName("accountStripeToken")
    @Expose
    private String accountStripeToken;
    @SerializedName("imageFileNameCSV")
    @Expose
    private String imageFileNameCSV;
    @SerializedName("videoFileNameCSV")
    @Expose
    private String videoFileNameCSV;
    @SerializedName("documentNameCSV")
    @Expose
    private String documentNameCSV;
    @SerializedName("description")
    @Expose
    private String description;

}
JakeWharton commented 7 years ago

You're calling set with null

NightlyNexus commented 7 years ago

The returned output of Converter.serialize must not be null. Can you share your Converter implementation?

maheshordex commented 6 years ago

Please check below code it is correct or i missed something.

 public static final String USER = "user";
 public Preference<User> user;

public MyPrefs (Context context, Gson gson){
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences (context);
        rxPreferences = RxSharedPreferences.create (preferences);
        user = rxPreferences.getObject(USER, new User (), new GsonAdapter<> (User.class));
  }

public class GSONData{
    public static Gson gson (){
        Gson gson = new GsonBuilder ().serializeNulls ().create ();
        return gson;
    }
}

public class GsonAdapter<T> implements Preference.Converter<T>{

        private Class<T> typeClass;

        public GsonAdapter (Class<T> typeClass){
            this.typeClass = typeClass;
        }

        @NonNull
        @Override
        public T deserialize (@NonNull String serialized){
            return GSONData.gson ().fromJson (serialized, typeClass);
        }

        @NonNull
        @Override
        public String serialize (@NonNull T value){
            return GSONData.gson ().toJson (value, typeClass);
        }
    }
NightlyNexus commented 6 years ago

I don't see a way that Gson.toJson returns null. If you can provide a failing example or test case, I can take a look.

Btw, I'd advise against making a new Gson instance every time you serialize. That requires creating a new TypeAdapter every time.

public final class GsonConverter<T> implements Preference.Converter<T> {
  private final TypeAdapter<T> adapter;

  public GsonAdapter(TypeAdapter<T> adapter) {
    this.adapter = adapter;
  }

  @NonNull @Override public T deserialize (@NonNull String serialized) {
    return adapter.fromJson(serialized);
  }

  @NonNull @Override public String serialize (@NonNull T value) {
    return adapter.toJson(value);
  }
}

rxPreferences.getObject(USER, DEFAULT_USER, new GsonConverter<>(gson.getAdapter(User.class)));
f2prateek commented 6 years ago

thanks for stepping in here @JakeWharton @NightlyNexus !

@maheshordex if you can provide a failing test case, that'd be the best way to get to the bottom of your issue.

maheshordex commented 6 years ago

@f2prateek @JakeWharton @NightlyNexus Thanks i got the issue.