Skip to content

Instantly share code, notes, and snippets.

@Ahmed-Adel-Ismail
Created August 27, 2017 22:42
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 Ahmed-Adel-Ismail/c0ec1ed6c8d37c931b3bf42b22430246 to your computer and use it in GitHub Desktop.
Save Ahmed-Adel-Ismail/c0ec1ed6c8d37c931b3bf42b22430246 to your computer and use it in GitHub Desktop.
A Model parent-class that survives rotation and configuration changes, all you need to do is call Model.of() in your onCreate, and Model.clear() in onDestroy, this code is based on this link : http://bcorso.github.io/android-retain-fragment/
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import java.lang.reflect.Constructor;
/**
* the parent class for all Model classes per application
*
* Created by Ahmed Adel Ismail on 8/28/2017.
*/
public class Model extends Fragment
{
@Override
@CallSuper
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
/**
* create an instance of the passed {@link Model} sub-class, if the instance already
* exists, it will be returned back
* @param activity the host {@link AppCompatActivity}
* @param modelClass the {@link Class} of the sub-class of the {@link Model}
* @param <T> the expected sub-class type
* @return the valid {@link Model} instance
* @throws RuntimeException if the initialization operation failed, make sure that all the
* {@link Model} sub-classes have default no-args constructor
* (or no declared constructors at all)
*/
@SuppressWarnings("unchecked")
public static <T extends Model> T of(AppCompatActivity activity, Class<T> modelClass)
throws RuntimeException {
FragmentManager fm = activity.getSupportFragmentManager();
T viewModel = (T) fm.findFragmentByTag(modelClass.getName());
if (viewModel == null) {
viewModel = createNewInstance(fm, modelClass);
}
return viewModel;
}
@SuppressWarnings("unchecked")
private static <T extends Model> T createNewInstance(FragmentManager fm, Class<T> modelClass) {
T viewModel = (T) constructModel(modelClass);
fm.beginTransaction()
.add(viewModel, modelClass.getName())
.commitAllowingStateLoss();
return viewModel;
}
private static Object constructModel(Class<?> modelClass) {
try {
Constructor constructor = modelClass.getDeclaredConstructor();
constructor.setAccessible(true);
return constructor.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* clear the current {@link Model} from memory
* @param activity the host {@link AppCompatActivity}
*/
public final void clear(AppCompatActivity activity) {
if (activity != null && activity.isFinishing()) {
doRemoveAndClearSubClasses(activity);
}
}
private void doRemoveAndClearSubClasses(AppCompatActivity activity) {
FragmentManager fm = activity.getSupportFragmentManager();
if (!fm.isDestroyed()) {
fm.beginTransaction().remove(this).commitAllowingStateLoss();
}
clear();
}
/**
* override this method by sub-classes to clear the references held by this instance
*/
protected void clear() {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment