Member preview

The danger of using getSimpleName() as TAG for Fragment

When we want to add a Fragment into a container of an Activity, we’ll normally use a TAG as it’s ID.

getFragmentManager().beginTransaction()
.add(containerResource, fragment, fragmentTAG).commit()

What’s a good TAG name we could use? It’s the class name itself. To simplify thing, maybe just use the simple name of the class, given we knew we never name any of our class the same name ever, even if they are in different packages.

public static final String TAG =         
MyClassFragment.class.getSimpleName();

Cool. When we debug and run, everything is good. Even in released proguard mode, they are fine without issue… until…

The Danger…

One day… we start to see some crashes. A very strange crash happen prior to adding the Fragment to the Activity. The error comes after we load the Fragment

fragment = getFragmentManager().findFragmentByTag(tag);

After some investigation, apparently the fragment loaded is a wrong fragment. How could that be?

Investigation…

After some debug, apparently the tag of my two different fragments is having the same tag name, despite the class name is different. Here is how it happens.

I have two fragments. After proguard, my fragments name changed to

com.mypackage.FragmentA → com.mypackage.c.a
com.mypackage.FragmentB → com.mypackage.c.a.a

That’s the post proguard full name. How about their short simple name i.e. getSimpleName()?

com.mypackage.FragmentA → a
com.mypackage.FragmentB → a

Wo! Wo! Wo!… The same name. No wonder when I try to find my fragment, it could potentially retrieve a wrong fragment…. when we are really really fortunate to have Proguard give the same simpleName for it.

Lesson Learned

I know the chance might not be high that the getSimpleName() will be the same on post proguard; but if it happens to me, it could happen to anyone. One should use either one of the below perhaps

  • the full name
  • canonical name
  • a constant explicitly defined