2017-01-05 9 views
0

に定義された一般化された静的関数がApplicationクラスを実装しています。この静的関数は、シリアライズされたクラスデータを共有プリファレンスとの間で格納および検索するジョブを実行します。Gsonを使用してSharedPreferencesに格納されたクラスデータをキャストすることができません

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; 
} 

私は以下のように、この静的関数を呼び出すために使用される:

AppController.saveObjectToSharedPreferences(getContext(), String.valueOf("UserData"), userDetailsObj); 

マイUserDetailsクラスは以下の通りです:

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に成功しましたuserdetailsオブジェクトをSharedPreferencesの形式で{'Name':'somename','UserGroup':'somegroup'}に保存しましたが、私はを取得していました。java.lang.Classを逆シリアル化しようとしました。タイプアダプタの登録を忘れましたか?readObjectFromSharedPreferencesの機能を使用して取得しようとしたときに、gson.fromJson行にあります。私はずっとこの問題で検索すると、私たちは、特に自分のTypeAdapterclassのために、私は言ったアダプタを実装し、AppController classonCreate中にgsonBuilder.registerTypeAdapterFactory(new ClassTypeAdapterFactory());を書いたthis answer hereの助けを借りて、私たちの書く必要があることを知りました。

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(); 
    } 
} 

は今、私はMethod threw 'com.google.gson.JsonSyntaxException' exception.と詳細メッセージjava.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 2 path $下を取得し始めました。

この時点では完全に空白です。誰かがこの仕事をするために正しい道を案内してくれますか?

+0

は、あなたが、私は両方@Pravinを登録する必要がありますregisterTypeAdapterFactoryとregisterTypeAdapter – Pavya

+0

を登録する必要がありますか? –

+0

私はそう思う! – Pavya

答えて

1

readObjectFromSharedPreferencesでは、Class<T> converterを渡しているとあなたがconverter.getClass()を呼び出しているとき、それはClassなくTを返します。ただ、このようなgetClass()コール削除します。また

return gson.fromJson(retrievedValue, converter); 

を、この方法を改善するための良い方法は、それがT代わりのObjectを返すようにすることです。この方法は、あなたは何をキャストする必要はありません。

public static <T> T readObjectFromSharedPreferences(...) 
+0

まさに..それは私が行方不明だった。私はTypeAdaptersや他の何ものも必要ありませんでした。 'T'の代わりに' GenericClass'を使用しました。それも良いだろうか? –

関連する問題