Skip to content

Instantly share code, notes, and snippets.

@kkuivi
Last active January 17, 2017 15:09
Show Gist options
  • Save kkuivi/d49d7d832013b2b15e28cf20706a013a to your computer and use it in GitHub Desktop.
Save kkuivi/d49d7d832013b2b15e28cf20706a013a to your computer and use it in GitHub Desktop.
ReferenceMap- Datastructure that makes it possible to pass objects between activities for Android development.
package com.goeshow.barcodescanner.utils.objectReferenceMap;
import android.content.Context;
import android.support.v4.app.Fragment;
import java.util.HashMap;
/**
* Created by ekuivi on 8/24/16.
*
* Singleton object that makes it easy to pass object references between activities
*/
public class ReferenceMap {
public class ReferenceList {
private HashMap<String, Object> mReferenceList;
private ReferenceList(){
mReferenceList = new HashMap<String, Object>();
}
public void put(String key, Object object){
mReferenceList.put(key, object);
}
public Object get(String key){
if(!mReferenceList.containsKey(key))
return null;
return mReferenceList.get(key);
}
}
private HashMap<String, ReferenceList> mRefListMap;
private static ReferenceMap mSingleInstance = null;
ReferenceMap(){
mRefListMap = new HashMap<String, ReferenceList>();
}
public static ReferenceMap getInstance(){
if(mSingleInstance == null)
mSingleInstance = new ReferenceMap();
return mSingleInstance;
}
private String getActivityNameFrom(Context context){
return context.getClass().getCanonicalName();
}
private String getFragmentNameFrom(Fragment fragment){
return fragment.getClass().getCanonicalName();
}
private String getActivityNameFrom(Class activity){
return activity.getCanonicalName();
}
public ReferenceList getReferenceList(Context context){
String activityName = getActivityNameFrom(context);
if(!mRefListMap.containsKey(activityName))
return null;
return mRefListMap.get(activityName);
}
public ReferenceList getReferenceList(Fragment fragment){
String fragmentName = getFragmentNameFrom(fragment);
if(!mRefListMap.containsKey(fragmentName))
return null;
return mRefListMap.get(fragmentName);
}
private void createActivityRefList(String activityName){
mRefListMap.put(activityName, new ReferenceList());
}
public void putObjectReference(Class activity, String objectKey, Object object){
String activtyName = getActivityNameFrom(activity);
if(!mRefListMap.containsKey(activtyName))
createActivityRefList(activtyName);
ReferenceList referenceList = mRefListMap.get(activtyName);
referenceList.put(objectKey, object);
}
public void releaseActivityRefList(Context context){
String activityName = getActivityNameFrom(context);
if(mRefListMap.containsKey(activityName))
mRefListMap.remove(activityName);
}
public void releaseFragmentRefList(Fragment fragment){
String fragmentName = getFragmentNameFrom(fragment);
if(mRefListMap.containsKey(fragmentName))
mRefListMap.remove(fragmentName);
}
}
@eduardb
Copy link

eduardb commented Oct 15, 2016

This is a very wrong approach, from my point of view. First of all, you'll be dependent on a global state, which is a singleton, a very bad practice in general. Then, you are also using Class.getSimpleName() as a key on your Map, which may lead to collisions. If you have ProGuard with obfuscation enabled, classes from different packages can end up with the same name, like a or b for instance. Thus, different activities will have the same simple name, and you'll overwrite and loose values in your map.

If you want to use Parcelables in a manner that is not error-prone, you can use AutoValue library from Google with an extension like https://github.com/rharter/auto-value-parcel.

@kkuivi
Copy link
Author

kkuivi commented Jan 17, 2017

Thanks, changed getSimpleName() to getCanonicalName(). This should solve the problem explained above. New version here (https://gist.github.com/kkuivi/161f254374a4007ae6014f67ae45789e)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment