Khang .NT
Khang .NT

Reputation: 1589

Android 10 - Weird activity lifecycle

I have a weird issue that happens on Android 10, when I start new landscape activity, the activity below will recreate.

Assume there're two Activity classes:

ActivityA: orientation = unspecified
ActivityB: orientation = force landscape, full screen, opaque

If I start ActivityB from ActivityA, the logs of lifecycle event:

D/ActivityA: onPause() called
D/ActivityB: onCreate() called
D/ActivityB: onStart() called
D/ActivityB: onResume() called
D/ActivityA: onStop() called
D/ActivityA: onDestroy() called
D/ActivityA: onCreate() called
D/ActivityA: onStart() called
D/ActivityA: onResume() called
D/ActivityA: onPause() called
D/ActivityA: onStop() called

Can clearly see that ActivityA is recreated, moreover somehow ActivityA#onResume is called after ActiviyB#onResume??

Okay, so now we have ActivityB on top of the stack, then I press back button:

D/ActivityB: onPause() called
D/ActivityA: onStart() called
D/ActivityA: onResume() called
D/ActivityA: onPause() called
D/ActivityA: onStop() called
D/ActivityA: onDestroy() called
D/ActivityA: onCreate() called
D/ActivityA: onStart() called
D/ActivityA: onResume() called
D/ActivityB: onStop() called
D/ActivityB: onDestroy() called

ActivityA is recreated again?

As I see in my device, there's an animation that ActivityA rotates into landscape mode before ActivityB becomes visible, and when ActivityB exits, ActivityA again rotates back to portrait mode. This behavior may cause ActivityA recreate again and again.

It messes up a lot, do you know how to prevent ActivityA recreate on this case, or this is a bug of Android itself?

UPDATE 1

I can handle configuration change on ActivityA easily, the problem is ActivityA has a very complex view structure, recreate it unnecessary causes UI lagging, moreover activity's lifecycle callback messy also cause broken logic.

UPDATE 2

I just figured out that recreate() method is invoked twice by AppCompatDelegateImpl class, that's why I get weird lifecycle behavior:

enter image description here

Upvotes: 2

Views: 1297

Answers (5)

Xid
Xid

Reputation: 4951

This looks like a device-specific bug.

I tried your code as it is on Pixel 3a (API 29 & 30) emulator. This is what I get:

On starting ActivityB from ActivityA:

D/MainActivityA: onPause() called
D/MainActivityB: onCreate() called
D/MainActivityB: onStart() called
D/MainActivityB: onResume() called
D/MainActivityA: onStop() called

On back button press:

D/MainActivityB: onPause() called
D/MainActivityA: onStart() called
D/MainActivityA: onResume() called
D/MainActivityB: onStop() called
D/MainActivityB: onDestroy() called

No weird animation indicating ActivityA is changing orientation

You should file an issue with the appropriate Android build and Device used

Thoughts on Update 2 in the question:

The logs show that onConfigurationChanged(Configuration) is being called. Documentation points out that Activity will be recreated on runtime configuration changes.

What you can do is override onConfigurationChanged(Configuration) in your Activity and log the Configuration object to see what device configuration was changed. It may be Orientation, Screen size, ScreenLayout or Keyboard availability

Upvotes: 1

SowlM
SowlM

Reputation: 992

Activity is recreated after each rotation by default as it's told on official Activity Lifecycle onDestroy() documents.

If you expect the activity’s UI state to remain the same throughout a configuration change, such as rotation, you should preserve the user’s transient UI state using a combination of ViewModel, onSaveInstanceState(), and/or local storage as it's explained in the Saving and restoring transient UI state

You can override this behavior with config changes attribute of the activity tag in AndroidManifest. For further details and different options, see Handle configuration changes

Finally, you can learn more about Activity Lifecycle in Context of Screen Rotation here.

Upvotes: 0

Technologeeks
Technologeeks

Reputation: 7897

Recreating activities on landscape/portrait is a feature of Android (not a bug) made by design because it's easier programmatically to just redraw the UI rather than figure out repositioning/resizing of elements. You should get the same effect when just flipping orientation on A even without B. This is also well described in the Android documentation (https://developer.android.com/guide/components/activities/state-changes#cco)

This shouldn't be too much of a problem, so long as you don't keep any references to the activity itself; The resources at this point are already cached, so there is little to no flash I/O, and most of the work will be recreating the views.

Upvotes: 1

David Wasser
David Wasser

Reputation: 95578

Probably isn't much you can do about this behaviour. I would suggest the following, if it doesn't cause you too many problems:

  • Add android:configChanges="orientation" to the manifest entry for ActivityA
  • Implement onConfigurationChanged() in ActivityA and handle the orientation change yourself

This will prevent Android from killing and recreating ActivityA during an orientation change.

Upvotes: 3

Shivansh Attri
Shivansh Attri

Reputation: 13

it's not only you facing this problem (many people are) this is a bug which is to be fixed and it shouldn't be messed actually can I know which device you are using? In comment you may tell.

Upvotes: 1

Related Questions