Status Update
Comments
il...@google.com <il...@google.com> #2
Branch: androidx-main
commit 57ca221882695bd6a52549f4d9ea3b812e6fe87c
Author: Simon Schiller <simonschiller@users.noreply.github.com>
Date: Mon Mar 22 16:09:30 2021
[GH] [FragmentStrictMode] Detect <fragment> tag usage
## Proposed Changes
- Detect `<fragment>` tag usage inside XML layouts
## Testing
Test: See `FragmentStrictModeTest#detectFragmentTagUsage`
## Issues Fixed
Fixes: 153738235
This is an imported pull request from
Resolves #141
Github-Pr-Head-Sha: 4ea052596e4341b9f11bcf335e2bc38045a91f19
GitOrigin-RevId: 62e7487aa4874eef6bb556490e193717cf937251
Change-Id: Iae48578e85e4e4897f806d7ade2e2a660adf9479
M fragment/fragment/api/public_plus_experimental_current.txt
M fragment/fragment/api/restricted_current.txt
M fragment/fragment/src/androidTest/java/androidx/fragment/app/strictmode/FragmentStrictModeTest.kt
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentLayoutInflaterFactory.java
M fragment/fragment/src/main/java/androidx/fragment/app/strictmode/FragmentStrictMode.java
A fragment/fragment/src/main/java/androidx/fragment/app/strictmode/FragmentTagUsageViolation.java
be...@gmail.com <be...@gmail.com> #3
visual check of the androidx library code (method androidx.fragment.app.FragmentManager.executeOpsTogether(...)) should be sufficient.
If I had access to the androidx.appcompat:appcompat:1.4.2 I would provide that code - nothing else is necessary, really.
Just check when java.util.ConcurrentModificationException is thrown.
Hints:
il...@google.com <il...@google.com> #4
Given that all operations on the FragmentManager are marked as MainThread
and must be single threaded, this is most certainly an issue with your code incorrectly committing a FragmentTransaction on a non-main thread, which is not supported.
We'd need to see your sample app that reproduces this issue to confirm as otherwise we'll have to mark this as not reproducible.
be...@gmail.com <be...@gmail.com> #5
It is not clear what part of my (quite big) application is causing the crash, it happens sometimes during the application start and only when it starts from widget, there is no problem when I am starting it from icon.
Now I know what to search for.
I will provide an info, if I can solve the issue, if not - I will contact you anyway...
be...@gmail.com <be...@gmail.com> #6
But as mentioned in the previous comment i could observe some issues during the start of my application:
- crashes (with no trace related to my app in logs)
- app doesn't show fragments sometimes after the start
- in some situation the back button has to be pressed twice to leave my main activity
After some investigation I can provide a simple example that shows some problems when the app is started from icon or widget respectively (code attached).
My application and the provided one have common problem - onCreate is called twice during the start!
Here is the use case:
1. install attached demo app
2. install widget and icon on the main screen
3. app shall not run in background
4. start app from icon
5. press back to leave app
6. start app from widget
7. press back - activity is closed, but the same activity is still shown
8. press back again - now activity will close
If you add log to the onCreate method you will see that onCreate is called twice
I am using the latest Android Studio with latest libs.
(I suspect that the new introduced Splashscreen is causing the issue).
Regards,
Cyril
be...@gmail.com <be...@gmail.com> #7
Demo was tested on Android 12 emulator and phone with the same result.
With "new introduced Splashscreen" I mean the splashscreen shown automatically in Android 12.
il...@google.com <il...@google.com>
to...@gmail.com <to...@gmail.com> #8
Jumping on this about #4 as I was about to open an issue about the lack of such annotation.
With android Fragment 1.5.2 (and from source 1.6.0 too) there's no Mainthread annotation on anything in that class.
And there's plenty of "Internet" comments about the fact that transaction are asynchronous and work from non main thread.
Would be nice if the annotation was indeed added (Just got caught in a stupid race with findFragmentByTag from a collect that was not done on main thread)
be...@gmail.com <be...@gmail.com> #9
2. I found a workaround for #6 (I had to manipulate back stack in manifest and in the code). Now I really suspect the automatic SplashScreen.
jb...@google.com <jb...@google.com> #10
All of our commit*()
functions should indeed be marked with @MainThread
to ensure they are only executed on the main thread.
ap...@google.com <ap...@google.com> #11
Branch: androidx-main
commit 95e15d8df12b8ce7cc32abdfd2e80dc667e893d6
Author: Jeremy Woods <jbwoods@google.com>
Date: Tue Mar 21 18:37:17 2023
Add @MainThread annotations to instant commit APIs
Adding @MainThread annotations to the commitNow,
executePendingTransactions, and popBackStackImmediate APIs to ensure we
get build time checks along with the runtime check already in place.
RelNote: "The fragment `commitNow()`, `executePendingTransactions()`,
and `popBackStackImmediate()` APIs will now all throw build errors when
they are not called from the main thread."
Test: all tests pass
Bug: 236538905
Change-Id: Ic966543935dd77a4c149cfc4b796bd912c558fb2
M fragment/fragment-ktx/api/current.txt
M fragment/fragment-ktx/api/public_plus_experimental_current.txt
M fragment/fragment-ktx/api/restricted_current.txt
M fragment/fragment-ktx/src/main/java/androidx/fragment/app/FragmentManager.kt
M fragment/fragment/api/current.txt
M fragment/fragment/api/public_plus_experimental_current.txt
M fragment/fragment/api/restricted_current.txt
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentTransaction.java
jb...@google.com <jb...@google.com> #12
This has been fixed internally and will be available in the the Fragment 1.6.0-alpha09
release.
na...@google.com <na...@google.com> #13
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.fragment:fragment:1.6.0-alpha09
androidx.fragment:fragment-ktx:1.6.0-alpha09
ma...@gmail.com <ma...@gmail.com> #14
I'm using fragment-ktx
version 1.6.1, and after an upgrade to androidx.navigation
2.7.1 (from 2.3.x) we started experiencing very similar issue:
E java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.next(ArrayList.java:860)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1915)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1845)
at androidx.fragment.app.FragmentManager.popBackStackImmediate(FragmentManager.java:891)
at androidx.fragment.app.FragmentManager.popBackStackImmediate(FragmentManager.java:797)
at androidx.fragment.app.FragmentManager.handleOnBackPressed(FragmentManager.java:717)
at androidx.fragment.app.FragmentManager$1.handleOnBackPressed(FragmentManager.java:447)
at androidx.activity.OnBackPressedDispatcher.onBackPressed(OnBackPressedDispatcher.kt:213)
at androidx.activity.OnBackPressedDispatcher$2.invoke(OnBackPressedDispatcher.kt:102)
at androidx.activity.OnBackPressedDispatcher$2.invoke(OnBackPressedDispatcher.kt:102)
at androidx.activity.OnBackPressedDispatcher$Api33Impl.createOnBackInvokedCallback$lambda$0(OnBackPressedDispatcher.kt:286)
at androidx.activity.OnBackPressedDispatcher$Api33Impl.$r8$lambda$tzBBo0FLedRCWSI6_icF8qhF74s(Unknown Source:0)
at androidx.activity.OnBackPressedDispatcher$Api33Impl$$ExternalSyntheticLambda0.onBackInvoked(Unknown Source:2)
at android.view.ViewRootImpl$NativePreImeInputStage.onProcess(ViewRootImpl.java:7558)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:7213)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:10788)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:10676)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:10632)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:10926)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:285)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:335)
at android.os.Looper.loopOnce(Looper.java:186)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8757)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
I wasn't able to come up with a repro yet, since this only happens occasionally. It seems it only happens when navigating back from a backstack with multiple entries. The app opts in the predictive back feature, it uses single navigation component graph + I haven't found single FragmentManager interaction that would be called outside of the scope of the main thread.
It looks like adding @MainThread
annotations wasn't enough, and people are still able to call FragmentManager methods the wrong way (I'm referring to code from latest stable navigation component library). Have you considered fixing the root cause of ConcurrentModificationException
? Or maybe it would be possible to help developers identify offending code (the ones that suposedly calls FragmentManager methods on a wrong thread)? Looking at the stacktrace it looks like the issue is fully within the FragmentManager implementation 🤷♂️
Description
Version used:
dependencies {
...
implementation 'androidx.appcompat:appcompat:1.4.2'
...
Devices/Android versions reproduced on: Samsung Galaxy Note 10 / Android 12
This is a problem in androidx library:
--------- beginning of crash
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: FATAL EXCEPTION: main
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: Process: sk.alteris.app.kalendarsk, PID: 6643
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: java.util.ConcurrentModificationException
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at java.util.ArrayList$Itr.next(ArrayList.java:860)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2184)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1971)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:311)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at androidx.fragment.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:274)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1244)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1092)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at androidx.viewpager.widget.ViewPager.onMeasure(ViewPager.java:1622)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.View.measure(View.java:27129)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.View.measure(View.java:27129)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.widget.LinearLayout.measureVertical(LinearLayout.java:995)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.View.measure(View.java:27129)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.widget.FrameLayout.onMeasure(FrameLayout.java:197)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:145)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.View.measure(View.java:27129)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at androidx.appcompat.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:496)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.View.measure(View.java:27129)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.widget.FrameLayout.onMeasure(FrameLayout.java:197)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.View.measure(View.java:27129)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1552)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.widget.LinearLayout.measureVertical(LinearLayout.java:842)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.widget.LinearLayout.onMeasure(LinearLayout.java:721)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.View.measure(View.java:27129)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7980)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.widget.FrameLayout.onMeasure(FrameLayout.java:197)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at com.android.internal.policy.DecorView.onMeasure(DecorView.java:1277)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.View.measure(View.java:27129)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:4528)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:3220)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3525)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2911)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:10458)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1108)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.Choreographer.doCallbacks(Choreographer.java:866)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.Choreographer.doFrame(Choreographer.java:797)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1092)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:938)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.os.Looper.loopOnce(Looper.java:226)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.os.Looper.loop(Looper.java:313)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:8663)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
06-20 19:51:20.465 10283 6643 6643 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
06-20 19:51:20.465 10227 7726 7726 I HWRResConfig: [setPreloadRootDirectoryPath] mPreloadRootDirPath is set with /product/HWRDB/
06-20 19:51:20.467 1000 966 1340 D SyncManager: userId - 0 auto - true
06-20 19:51:20.469 1000 966 1544 D Debug : low && ship && 3rdparty app crash, do not dump
06-20 19:51:20.469 1000 966 1544 W ActivityManager: crash : sk.alteris.app.kalendarsk,10283