Saturday, December 7, 2013

requestFeature() must be called before adding content

Lets start with the reason for this error:

YOU MUST NOT REQUEST A WINDOW FEATURE, AFTER ADDING CONTENT TO UI ENTITY.

By UI Entity I mean, Activity or dialog, etc.

I had a unique desire... to rebuild my Activity and its content upon language switching from a menu I've build here, without the Activity re-creation which most times causes flickering

Well that was not a complicated task, but quite surprising that I had to use this:

private static Field windowContentParent;

static {
    try {
        windowContentParent = Class.forName("com.android.internal.policy.impl.PhoneWindow").getDeclaredField("mContentParent");
        windowContentParent.setAccessible(true);
    } catch (Exception e) {
        Log.e("REFLECTION STATIC", "Cannot extract PhoneWindow.mContentParent Field");
    }
}


And then when you want to remove the content: 


View rootView = screen.getRootView();
((ViewGroup) rootView.getParent()).removeAllViews();
windowContentParent.set(getWindow(), null);

 



Why does this work?

The only thing indicating that the content had been set is the parent instance of the window, once you turn it to null, it is as if your activity had just been created.

Although this works for me, and on every android version I've tested(2.1 - 4.4), this is very hackey... Use this with caution!!!


---- UPDATE ----

Well, I should have wrote: USE THIS WITH CAUTION!!!!
I've just spent a couple of hour debugging an issue where an entity within the activity registers as a listener, and since the life cycle of the activity was not called, bad things happened, from weird UI behavior, to memory leaks...

So be careful! and be smart... I've ended up performing the terminating life cycle of the activity by calling pause, stop, destroy, logic, without calling onPause, onStop, onDestroy.