Android-Animated-Theme-Manager icon indicating copy to clipboard operation
Android-Animated-Theme-Manager copied to clipboard

Cannot start animation on a detached view for a resumed Activity.

Open IODevBlue opened this issue 2 years ago • 0 comments

Although I easily fixed this issue, the solution should be included in the next update.

I'd give a bit of context on why this happened and how to recreate the problem.

I have a base class BaseActivity which extends ThemeActivity. All my Activity classes extend BaseActivity and so can override syncTheme() and getStartTheme().

Let's say I start from MainActivity which extends BaseActivity and in it's onCreate() it calls ThemeManager.init(activity, getStartTheme()). This happens from the ThemeActivity super class.

However when I navigate to another class say SecondActivity, this is what happens.

  • onStop() of MainActivity is called.
  • onCreate() of SecondActivity is called and this is where the ThemeManager instance is initialized again (from the super class ThemeActivity) and changes private activity variable from MainActivity to SecondActivity. This is fine as the current Context would be SecondActivity.

But when I navigate back to MainActivity, this is what happens.

  • onStop() for SecondActivity is called.
  • onRestart() for MainActivity is called. Since the MainActivity is not destroyed and remained on the heap, it just stopped and restarted. It's onCreate() was not called and that means the activity variable in the ThemeManager instance that was reinstantiated when SecondActivity was navigated to still has the private activity variable as the SecondActivity instance (which should have been destroyed when navigated back up). This is a resource leak.

And so whenever I try to change theme in MainActivity, I get a "Cannot run animation on a detached View" error from the ViewAnimator.

I fixed this error by reinstantiating ThemeManager by calling ThemeManager.init(activity, getStartTheme()) in the onRestart() of MainActivity and that fixed my issue.

So I feel onRestart() should be overriden in ThemeActivity and ThemeManager should reinstantiated on that callback.

I did a debug on my code when carrying out the above scenario and found that issue out.

IODevBlue avatar Oct 14 '22 13:10 IODevBlue