Obtain styleable fields at runtime

Ususally, when we want to get some “R” attributes at runtime, we use the Resources getIdentifier method, which is useful for getting strings, drawables and ids at runtime. Unfortunately this method cannot be used to get the styleable fields. However, using java reflections, there’s another way to solve the problem. With this snippet you can get styleable fields at runtime in your code:

[cce]public static final <T> T getFieldFromStyleable( Context context, String name ) {
try {
// use reflection to access the resource class
Field field = Class.forName( context.getPackageName() + “.R$styleable” ).getField( name );
if ( null != field ) {
return (T) field.get( null );
}
} catch ( Throwable t ) {
t.printStackTrace();
}
return null;
}[/cce]

Which can be used in this way:
[cce]int[] array = getFieldFromStyleable( context, “MyListView” );
array = context.obtainStyledAttributes( attrs, styleableArray, defStyle, 0 );[/cce]

Playing with a LocalActivityManager bug

If you already used the ActivityGroup class you probably used also the LocalActivityManager instance to manage your group’s activities. I was creating my activity which should also manages its internal history ( using a ViewFlipper for animating the activity views ).
The problem came out once I tried to destroy an activity from the history using the LocalActivityManager destroy method. After an activity was removed from both my internal history and from the local activity manager I was unable to create a new instance of the same activity.

After googling for my problem I found that it was because a bug in the LocalActivityManager class: http://code.google.com/p/android/issues/detail?id=12359
This is exactly my problem! In fact, debugging the android code ( see this post for debugging android code ) at that point it was clear that the record it’s not removed from the internal mActivities map.

Fortunately there are Reflections which can help me! I added this piece of code after the call to the destroy method:


Field mActivitiesField = getLocalActivityManager().getClass().getDeclaredField( "mActivities" );
mActivitiesField.setAccessible( true );
((Map) mActivitiesField.get( getLocalActivityManager() )).remove( id );

and that trick does the job