Android main module is starting twice due to configuration change
- Dominant language
- Python
- Stars
- 3.3k
- Forks
- 549
- Avg merge
- 1d 4h
- Merged PRs (30d)
- 40
Description
### Describe the bug
I am currently working on an [Android bleak PR](https://github.com/hbldh/bleak/pull/1944). The BLE API slightly differs between different API levels so I tried to run the integration tests on different emulators with different API levels (31-36). I noticed, that the emulator on API level 35 and 36 are often failing or hanging completely, when running on Github Actions. Locally I could not reproduce the error. Here is an example of such an [failing CI run](https://github.com/timrid/bleak/actions/runs/24894304106/job/72894763976). That uses `system-images;android-36;default;x86_64` and I added a script to show more logcat output than usual, for example to see the `ActivityTaskManager` output.
I noticed, that on the API 35 and 36 emulators the `onDestroy` method is called when the CI run fails. The `onDestroy` call is followed by a second `onCreate` call. In the second `onCreate` call you can see `D/MainActivity: Python already started` in the logs. And then later you can see that my pytests are running twice. E.g. the line
```
I/python.stdout: platform android -- Python 3.13.9, pytest-9.0.3, pluggy-1.6.0 -- /system/bin/app_process64
````
is twice in the logs. So I guess that this is the cause of my error, that my test script is running twice in parallel.
But why is is the `onDestroy` is called in the first place? I guess it is because of the config change
```
04-24 14:21:10.895 668 697 I ActivityTaskManager: Config changes=80000000 {1.0 310mcc260mnc [en_US] ldltr sw411dp w411dp h731dp 420dpi nrml long port finger qwerty/v/v dpad/v winConfig={ mBounds=Rect(0, 0 - 1080, 1920) mAppBounds=Rect(0, 0 - 1080, 1920) mMaxBounds=Rect(0, 0 - 1080, 1920) mDisplayRotation=ROTATION_0 mWindowingMode=fullscreen mActivityType=undefined mAlwaysOnTop=undefined mRotation=ROTATION_0} as.2 s.22 fontWeightAdjustment=0}
```
that occurs *after* the first `onCreate` is called and so an [app recreation](https://developer.android.com/guide/topics/resources/runtime-changes) is triggered. On the API level 31-34 this config change always occurs before my app is started an thus the app recreation is not triggered.
At first I thought that maybe only the emulator boot complete detection is wrong, but then I saw in the Android docs, that an app recreation can always happen and some of the recreations [cannot be suppressed](https://developer.android.com/guide/topics/resources/runtime-changes). So probably the handling of the Android app recreation is not correctly.
### How to reproduce the bug
1. Fork my branch `https://github.com/timrid/bleak/commits/android-35-and-36-bug` and start the [build_and_test.yml](https://github.com/timrid/bleak/blob/develop/.github/workflows/build_and_test.yml) Github Actions run manually via workflow dispatch
2. Look at the CI output of the `Android integration tests (3.13, 35)` or `Android integration tests (3.13, 36)`. Sometimes they fail with random errors or hang up completely. The runs using a API 31-34 emulator runs without problems.
### Minimum example code
```shell
```
### Screenshots
_No response_
### Environment details
- Operating system and version: Ubuntu (Github Actions CI)
- Python version: 3.13
- Software versions:
- Briefcase: [5610048a07ff79ebaf2048d28c7fdc9bda9b327c](https://github.com/beeware/briefcase/commit/5610048a07ff79ebaf2048d28c7fdc9bda9b327c)
- Toga: [199b0fa751d944b9c83c5d29602c263a2fda3cd2](https://github.com/beeware/toga/commit/199b0fa751d944b9c83c5d29602c263a2fda3cd2)
- ...
### Logs
[job-logs.txt](https://github.com/user-attachments/files/27057109/job-logs.txt)
### Additional context
When looking at the [`onCreate` of the briefcase-android-gradle-template](https://github.com/beeware/briefcase-android-gradle-template/blob/184b6ed055bff4aeefb4517525cb190a3dba1eff/%7B%7B%20cookiecutter.format%20%7D%7D/app/src/main/java/org/beeware/android/MainActivity.java#L54) , I noticed that this uses the `Activity.onCreate` to starte the Python interpreter and start the main script and not the `Application.onCreate` as [suggested in the chaquopy docs](https://chaquo.com/chaquopy/doc/current/android.html#android-startup). Maybe this is part of the reason.
Contributor guide
Assessment
This issue has not been assessed yet.