Status Update
Comments
ra...@google.com <ra...@google.com> #2
Is this specific to navigation? Or can this be reproduced with another other Composable component?
st...@deliveroo.co.uk <st...@deliveroo.co.uk> #3
It only happens inside of a NavHost. So, yes, it seems to be specific to navigation.
da...@google.com <da...@google.com> #4
This was caused by the fix to BackHandler
lifecycle aware. The problem here is that the NavController
registers its lifecycle and added an observer to the Activity
Lifecycle
in composition while the BackHandler
registers its observer on the Activity
Lifecycle
in a DisposbleEffect
. This means that the NavController
will always get Lifecycle callbacks before the BackHandler
, so the components listening the the NavController
's lifecycle (like the NavBackStackEntry) will always get their Lifecycle callbacks before the BackHandler
as well.
This should be addressed by work coming in 2.7 to integrate the BackHandler
into the NavHost
.
ra...@google.com <ra...@google.com> #5
Branch: androidx-main
commit d2c5efe67531a30fb9f1a129d52beb1e9ece0b29
Author: Jeremy Woods <jbwoods@google.com>
Date: Wed May 31 23:09:54 2023
Integrate BackHandler into NavHost
Instead of NavHost taking over the onBackPressedDispatcher from the
Activity, we should just make it use a BackHandler. This will ensure
that it interacters with the other BackHandlers in Compose correctly.
RelNote: "`NavHost` now correctly intercepts system back calls even
after the Activity has been `STOPPED` and `RESUMED`."
Test: modified tests
Bug: 279118447
Change-Id: Icb6deab996d122487243f0d3d775af8c15fc7c25
M navigation/navigation-compose/src/androidTest/java/androidx/navigation/compose/NavHostTest.kt
M navigation/navigation-compose/src/main/java/androidx/navigation/compose/NavHost.kt
st...@deliveroo.co.uk <st...@deliveroo.co.uk> #6
This has been fixed internally and will be available in Navigation 2.7.0-beta01.
st...@deliveroo.co.uk <st...@deliveroo.co.uk> #7
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.navigation:navigation-compose:2.7.0-beta01
va...@gmail.com <va...@gmail.com> #8
da...@google.com <da...@google.com> #9
I wouldn't say this is fixed. If you add a back-callback in the activity which is lifecycle aware, and then background->foreground the app, the activity back-callback will be put on top of the callback pile. This leads to that any BackHandler in your composable will NOT be triggered.
The best workaround I have for now is to use the non-lifecycle aware function in the activity.
class MainActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// open fragment which hoists the composables
...
if (savedInstanceState == null) {
onBackPressedDispatcher.addCallback(onBackPressedCallback = someBackHandling())
// onBackPressedDispatcher.addCallback(owner = this, onBackPressedCallback = someBackHandling) // not this one
}
}
ap...@google.com <ap...@google.com> #10
ap...@google.com <ap...@google.com> #11
rw...@gmail.com <rw...@gmail.com> #12
Bug Fixes : NavHost in Navigation Compose now correctly intercepts system back calls even after the Activity has been STOPPED and RESUMED.
It works fine for me.
Description
Version used: 2.9.0
Devices/Android versions reproduced on: API 34
When we target API 34, WorkManager is crashing our application on startup if the "location" permissions are removed whilst the application is running.
Everything works fine whilst the application has the "location" permissions. When the "location" permissions are removed (whilst the application is running), the OS is killing the application (OS behaviour) and because SystemForegroundService is a STICKY service, the OS tries to restart the service which causes a security exception because the "location" permissions are no longer present.
This is a realistic user scenario which will happen many times in our production app. We can not prevent our application from crashing as this relates to the STICKY SystemForegroundService. Our application, can check the "location" permissions before scheduling the "worker", but we have no control over the user removing the "location" permissions after the "worker" has been scheduled by the WorkManager.
This behaviour only happens with WorkManager when targeting API 34 as per the restrictions documented here:
Here is the crash we are seeing on application startup:
Java.lang.SecurityException: Starting FGS with type location callerApp=ProcessRecord{34bbf76 32120:com.deliveroo.driverapp.test/u0a190} targetSDK=34 requires permissions: all of the permissions allOf=true [android.permission.FOREGROUND_SERVICE_LOCATION] any of the permissions allOf=false [android.permission.ACCESS_COARSE_LOCATION, android.permission.ACCESS_FINE_LOCATION] and the app must be in the eligible state/exemptions to access the foreground only permission
We are using the WorkManager to run a CoroutineWorker which accesses the device location. We are scheduling the Worker as follows:
val request = OneTimeWorkRequest.Builder(worker.java)
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
.build()
WorkManager.getInstance(context).enqueueUniqueWork(
ExistingWorkPolicy.KEEP,
request,
)
We are specifying FOREGROUND_SERVICE_TYPE_LOCATION in the ForegroundInfo:
ForegroundInfo(ONLINE_NOTIFICATION_ID, notificationsManager.onlineNotification, ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION)
Our Android manifest specifies the "location" foregroundServiceType:
<service
android:name="androidx.work.impl.foreground.SystemForegroundService"
android:foregroundServiceType="location"/>
As stated above, everything works fine until the user removes the "location" permissions after the "worker" has started. Then the OS kills our application and the OS tries to recover the STICKY SystemForegroundService which crashes because the app no longer as "location" permissions.
Please can you advise how we can avoid WorkManager crashing our application in the above scenario.