Skip to content

Instantly share code, notes, and snippets.

@lin1987www
Last active September 10, 2015 07:37
Show Gist options
  • Save lin1987www/00234a8126ff29f330a6 to your computer and use it in GitHub Desktop.
Save lin1987www/00234a8126ff29f330a6 to your computer and use it in GitHub Desktop.
EventBus.StickyEventKeeper
package com.lin1987www.app;
import android.os.Bundle;
import android.os.Parcel;
import android.util.Log;
import java.lang.reflect.Field;
import java.util.Map;
import de.greenrobot.event.EventBus;
/**
* Created by lin on 2014/9/1.
*/
public class EventBusUtils {
public final static String TAG = EventBusUtils.class.getName();
private final static Field stickyEventsField;
static {
Field f = null;
try {
f = EventBus.class.getDeclaredField("stickyEvents");
f.setAccessible(true);
} catch (NoSuchFieldException e) {
Log.e(TAG, "Error getting stickyEvents field", e);
}
stickyEventsField = f;
}
public static Map<Class<?>, Object> getStickyEvents(EventBus eventBus){
Map<Class<?>, Object> stickyEvents = null;
if (stickyEventsField != null) {
try {
stickyEvents = (Map<Class<?>, Object>)stickyEventsField.get(eventBus);
} catch (Exception e) {
Log.e(TAG, "Error setting mChildFragmentManager field", e);
}
}
return stickyEvents;
}
}
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// Load EventBus StickyEvent
ParcelableManager.getDefaultParcelableManager().onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
}
@Override
protected void onSaveInstanceState(android.os.Bundle outState) {
super.onSaveInstanceState(outState);
// Save EventBus StickyEvent
ParcelableManager.getDefaultParcelableManager().add(new StickyEventKeeper());
ParcelableManager.getDefaultParcelableManager().onSaveInstanceState(outState);
}
}
package com.lin1987www.app;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by lin on 2014/9/1.
*/
public abstract class ParcelableKeeper<T extends Parcelable> implements Parcelable {
public final static String TAG = ParcelableKeeper.class.getName();
public String className;
public Parcelable data;
public ParcelableKeeper() {
}
public ParcelableKeeper(Parcel in) {
try {
this.className = in.readString();
Class<?> objClass = Class.forName(className);
this.data = in.readParcelable(objClass.getClassLoader());
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
public void onRestoreInstanceState() {
loadDate(getData());
}
public void onSaveInstanceState() {
setData(saveData());
}
public abstract void loadDate(T data);
public abstract T saveData();
private T getData() {
return (T) data;
}
private void setData(T data) {
this.className = data.getClass().getName();
this.data = data;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.className);
dest.writeParcelable(this.data, 0);
}
@Override
public int describeContents() {
return 0;
}
}
package com.lin1987www.app;
import android.os.Bundle;
/**
* Created by lin on 2014/9/1.
* StateManager is helping Bundle data to save.
*/
public class ParcelableManager {
private static ParcelableManager defaultParcelableManager;
private Bundle data = new Bundle();
public static ParcelableManager getDefaultParcelableManager() {
if (defaultParcelableManager == null) {
synchronized (ParcelableManager.class) {
if (defaultParcelableManager == null) {
defaultParcelableManager = new ParcelableManager();
}
}
}
return defaultParcelableManager;
}
public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState == null) {
return;
}
data = savedInstanceState.getParcelable(this.getClass().getName());
for (String className : data.keySet()) {
ParcelableKeeper<?> parcelableKeeper = (ParcelableKeeper<?>) data.get(className);
parcelableKeeper.onRestoreInstanceState();
}
}
public void onSaveInstanceState(Bundle outState) {
for (String className : data.keySet()) {
ParcelableKeeper<?> parcelableKeeper = (ParcelableKeeper<?>) data.get(className);
parcelableKeeper.onSaveInstanceState();
}
outState.putParcelable(this.getClass().getName(), data);
}
public void add(ParcelableKeeper<?> parcelableKeeper) {
data.putParcelable(parcelableKeeper.getClass().getName(), parcelableKeeper);
}
}
package com.lin1987www.app;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Map;
import de.greenrobot.event.EventBus;
/**
* Created by lin on 2014/9/1.
*/
public class StickyEventKeeper extends ParcelableKeeper<StickyEventMap> {
public StickyEventKeeper(){super();}
public StickyEventKeeper(Parcel in) {super(in);}
@Override
public void loadDate(StickyEventMap data) {
// Recover data by postSticky
Map<String, Parcelable> stickyEvents = data.stickyEvents;
for (String className : stickyEvents.keySet()) {
Object obj = stickyEvents.get(className);
EventBus.getDefault().postSticky(obj);
}
}
@Override
public StickyEventMap saveData() {
// Save Default EventBus
return new StickyEventMap(EventBus.getDefault());
}
public static final Creator<StickyEventKeeper> CREATOR = new Creator<StickyEventKeeper>() {
public StickyEventKeeper createFromParcel(Parcel source) {
return new StickyEventKeeper(source);
}
public StickyEventKeeper[] newArray(int size) {
return new StickyEventKeeper[size];
}
};
}
package com.lin1987www.app;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.HashMap;
import java.util.Map;
import de.greenrobot.event.EventBus;
public class StickyEventMap implements Parcelable {
public final Map<String, Parcelable> stickyEvents = new HashMap<String, Parcelable>();
public StickyEventMap(EventBus eventBus) {
Map<Class<?>, Object> map = EventBusUtils.getStickyEvents(eventBus);
for (Class<?> objClass : map.keySet()) {
Object obj = map.get(objClass);
if (obj instanceof Parcelable) {
stickyEvents.put(objClass.getName(), (Parcelable) obj);
}
}
}
private StickyEventMap(Parcel in) {
// Try save all objects who implements Parcelable sticky events
try {
int size = in.readInt();
for (int i = 0; i < size; i++) {
String className = in.readString();
Class<?> objClass = Class.forName(className);
Parcelable obj = in.readParcelable(objClass.getClassLoader());
stickyEvents.put(className, obj);
}
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
int size = stickyEvents.size();
dest.writeInt(size);
for (String className : stickyEvents.keySet()) {
dest.writeString(className);
dest.writeParcelable(stickyEvents.get(className), 0);
}
}
public static final Creator<StickyEventMap> CREATOR = new Creator<StickyEventMap>() {
public StickyEventMap createFromParcel(Parcel source) {
return new StickyEventMap(source);
}
public StickyEventMap[] newArray(int size) {
return new StickyEventMap[size];
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment