Skip to content

Instantly share code, notes, and snippets.

@bulwinkel
Created July 31, 2016 23:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bulwinkel/30eef5a5bd53e76c55776ab73829a65c to your computer and use it in GitHub Desktop.
Save bulwinkel/30eef5a5bd53e76c55776ab73829a65c to your computer and use it in GitHub Desktop.
Serialize Properties into Bundles and back (Experimental)
import android.os.Bundle;
import com.squareup.moshi.JsonAdapter;
import com.squareup.moshi.Moshi;
import java.io.IOException;
/**
* Removes some of the boilerplate associated with Properties in android fragments by handling
* the serialization and deserialization of wrapped objects into and out of argument
* {@link Bundle}s.
*
* Depends on Moshi, but could easily be adapted to Gson.
*
* <pre>
* {@code
*
* private final SerializedProperty<School> school = SerializedProperty.create(School.class);
*
* ...
*
* public static SelectDepartmentFragment create(School school) {
* final SelectDepartmentFragment fragment = new SelectDepartmentFragment();
* final Bundle args = new Bundle();
* fragment.school.set(school).saveTo(args);
* fragment.setArguments(args);
* return fragment;
* }
*
* ...
*
* @Override public void onCreate(@Nullable Bundle savedInstanceState) {
* super.onCreate(savedInstanceState);
* school.setFrom(getArguments());
* }
* }
* </pre>
*
* @param <T> Type of the object wrapped object.
*/
public class SerializedProperty<T> {
private static final Moshi moshi = new Moshi.Builder().build();
/**
* Creates a {@link SerializedProperty} for the given type, with the given key.
*
* @param type Class of the property to be wrapped
* @param <T> type of the property to be wrapped
* @return an instance of {@link SerializedProperty} for the given type
*/
public static <T> SerializedProperty<T> create(Class<T> type, String key) {
return new SerializedProperty<>(type, key);
}
/**
* Creates a {@link SerializedProperty} for the given type, since no {@link #key} is
* explicitly specified the {@link Class#getSimpleName()} will be used.
*
* @param type Class of the property to be wrapped
* @param <T> type of the property to be wrapped
* @return an instance of {@link SerializedProperty} for the given type
*/
public static <T> SerializedProperty<T> create(Class<T> type) {
return new SerializedProperty<>(type, type.getSimpleName());
}
private final JsonAdapter<T> adapter;
private final String key;
public String getKey() { return key; }
private T object;
public T get() { return object; }
public SerializedProperty<T> set(T object) {
this.object = object;
return this;
}
private SerializedProperty(Class<T> type, String key) {
adapter = moshi.adapter(type);
this.key = key;
}
/**
* @param bundle
* @return true if wrapped property successfully set
*/
public boolean setFrom(Bundle bundle) {
if (bundle == null) {
return false;
}
final String serialized = bundle.getString(getKey());
if (serialized == null) {
return false;
}
try {
object = adapter.fromJson(serialized);
return true;
} catch (IOException e) {
return false;
}
}
/** Stores a copy of the wrapped object in the given bundle. */
public boolean saveTo(Bundle bundle) {
final String value = adapter.toJson(get());
bundle.putString(getKey(), value);
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment