Reputation: 29683
I am having a generalized static function defined in AppController.java
which implements Application
class. This static function does a job of storing and retrieving serialized class data to and from shared preferences.
AppController.java
private static GsonBuilder gsonBuilder;
@Override
public void onCreate() {
super.onCreate();
gsonBuilder= new GsonBuilder();
}
public static void saveObjectToSharedPreferences(Context mContext,String key, Object value){
if(mContext!=null){
SharedPreferences mSharedPreferences=mContext.getSharedPreferences(SHARED_PREFS,MODE_PRIVATE);
if(mSharedPreferences!=null) {
Gson gson=gsonBuilder.excludeFieldsWithoutExposeAnnotation().create();
String storableValue=gson.toJson(value,value.getClass());
mSharedPreferences.edit().putString(key,storableValue).apply();
}
}
}
public static <T> Object readObjectFromSharedPreferences(Context mContext,String key, Class<T> converter ){
if(mContext!=null){
SharedPreferences mSharedPreferences = mContext.getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
if(mSharedPreferences!=null){
Gson gson=gsonBuilder.excludeFieldsWithoutExposeAnnotation().create();
String retrievedValue=mSharedPreferences.getString(key,null);
if(retrievedValue!=null){
return gson.fromJson(retrievedValue,converter.getClass());
}
}
}
return null;
}
I used to call this static functions as below:
AppController.saveObjectToSharedPreferences(getContext(), String.valueOf("UserData"), userDetailsObj);
My UserDetails
class is as below:
public class UserDetails implements Serializable{
@Expose
private String Name;
@Expose
private String UserGroup;
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getUserGroup() {
return UserGroup;
}
public void setUserGroup(String userGroup) {
UserGroup = userGroup;
}
}
saveObjectToSharedPreferences
was successfully saving the userdetails
object into SharedPreferences
in the format {'Name':'somename','UserGroup':'somegroup'}
but I was getting Attempted to deserialize java.lang.Class. Forgot to register a type adapter?, when I tried to retrieve it using readObjectFromSharedPreferences
function in gson.fromJson
line. When I searched for this issue throughout, I got to know that we need to specifically write our own TypeAdapter
for class
and with the help of this answer here I implemented the said Adapters and wrote gsonBuilder.registerTypeAdapterFactory(new ClassTypeAdapterFactory());
during onCreate
of AppController class
.
public class ClassTypeAdapterFactory implements TypeAdapterFactory {
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
if(!Class.class.isAssignableFrom(typeToken.getRawType())) {
return null;
}
return (TypeAdapter<T>) new ClassTypeAdapter();
}
}
Now I've started getting Method threw 'com.google.gson.JsonSyntaxException' exception.
and under detailed message java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 2 path $
.
I am totally blank at this point of time. Could someone please guide me in the right path to make this work?
Upvotes: 1
Views: 115
Reputation: 15064
In readObjectFromSharedPreferences
you are passing Class<T> converter
and when you are calling converter.getClass()
it returns Class
and not T
. Just remove the getClass()
call like this:
return gson.fromJson(retrievedValue, converter);
Also, a nice way to improve this method is to make it return T
instead of Object
. This way you won't have to cast anything:
public static <T> T readObjectFromSharedPreferences(...)
Upvotes: 2