Fixed
Status Update
Comments
il...@google.com <il...@google.com>
ap...@google.com <ap...@google.com> #2
Project: platform/frameworks/support
Branch: androidx-master-dev
commit c7782e3df384027df9484f615880a22d26975f18
Author: Ian Lake <ilake@google.com>
Date: Wed Jul 10 10:53:39 2019
Fall back to commitAllowingStateLoss() on ISE
When FragmentPagerAdapter or FragmentStatePagerAdapter
runs finishUpdate() in response to a measure/layout
pass, it runs commitNowAllowingStateLoss() as all
normal devices don't do measure/layout while processing
pending FragmentTransactions.
However, with b/135945162 , FragmentManager does call
requestApplyInsets() as part of processing Fragments.
This gets posted on real devices, but Robolectric will
run it inline, causing this to throw an
IllegalStateException. To ensure that Robolectric
continues to work, we can call commitAllowingStateLoss()
in this particular case to ensure that it runs even
while pending FragmentTransactions are being processed.
Test: manual testing
Fixes: 137201343
Change-Id: I62b6312ffbd754af6c6bedf0f1adc30c40641575
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentPagerAdapter.java
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentStatePagerAdapter.java
https://android-review.googlesource.com/1013911
https://goto.google.com/android-sha1/c7782e3df384027df9484f615880a22d26975f18
Branch: androidx-master-dev
commit c7782e3df384027df9484f615880a22d26975f18
Author: Ian Lake <ilake@google.com>
Date: Wed Jul 10 10:53:39 2019
Fall back to commitAllowingStateLoss() on ISE
When FragmentPagerAdapter or FragmentStatePagerAdapter
runs finishUpdate() in response to a measure/layout
pass, it runs commitNowAllowingStateLoss() as all
normal devices don't do measure/layout while processing
pending FragmentTransactions.
However, with
requestApplyInsets() as part of processing Fragments.
This gets posted on real devices, but Robolectric will
run it inline, causing this to throw an
IllegalStateException. To ensure that Robolectric
continues to work, we can call commitAllowingStateLoss()
in this particular case to ensure that it runs even
while pending FragmentTransactions are being processed.
Test: manual testing
Fixes: 137201343
Change-Id: I62b6312ffbd754af6c6bedf0f1adc30c40641575
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentPagerAdapter.java
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentStatePagerAdapter.java
om...@gmail.com <om...@gmail.com> #3
Using version: fragmentx: 1.2.0-rc4
If multiple finishUpdate() calls are made, it is possible that commitNowAllowingStateLoss() can throw multiple IllegalStateExceptions, which will cause an NPE since mCurTransaction is set to null after the try/catch method. See the stacktrace below:
java.lang.NullPointerException
at androidx.fragment.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:267)
at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1244)
at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1092)
at androidx.viewpager.widget.ViewPager.onMeasure(ViewPager.java:1622)
at android.view.View.measure(View.java:22071)
at androidx.constraintlayout.widget.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:1227)
at androidx.constraintlayout.widget.ConstraintLayout.onMeasure(ConstraintLayout.java:1572)
at android.view.View.measure(View.java:22071)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:22071)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
at android.view.View.measure(View.java:22071)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:806)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
at android.view.View.measure(View.java:22071)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:22071)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:806)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
at android.view.View.measure(View.java:22071)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:724)
at android.view.View.measure(View.java:22071)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2422)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1504)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1761)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1392)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6752)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at org.robolectric.shadows.ShadowMessageQueue.dispatchMessage(ShadowMessageQueue.java:148)
at org.robolectric.shadows.ShadowMessageQueue.access$200(ShadowMessageQueue.java:38)
at org.robolectric.shadows.ShadowMessageQueue$1.run(ShadowMessageQueue.java:126)
at org.robolectric.util.Scheduler$ScheduledRunnable.run(Scheduler.java:386)
at org.robolectric.util.Scheduler.runOneTask(Scheduler.java:278)
at org.robolectric.util.Scheduler.advanceTo(Scheduler.java:260)
at org.robolectric.util.Scheduler.advanceBy(Scheduler.java:243)
at org.robolectric.util.Scheduler.advanceBy(Scheduler.java:233)
at org.robolectric.util.Scheduler.setIdleState(Scheduler.java:88)
at org.robolectric.util.Scheduler.unPause(Scheduler.java:123)
at org.robolectric.shadows.ShadowLooper.unPause(ShadowLooper.java:347)
at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:398)
at org.robolectric.android.controller.ActivityController.visible(ActivityController.java:161)
If multiple finishUpdate() calls are made, it is possible that commitNowAllowingStateLoss() can throw multiple IllegalStateExceptions, which will cause an NPE since mCurTransaction is set to null after the try/catch method. See the stacktrace below:
java.lang.NullPointerException
at androidx.fragment.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:267)
at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1244)
at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1092)
at androidx.viewpager.widget.ViewPager.onMeasure(ViewPager.java:1622)
at android.view.View.measure(View.java:22071)
at androidx.constraintlayout.widget.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:1227)
at androidx.constraintlayout.widget.ConstraintLayout.onMeasure(ConstraintLayout.java:1572)
at android.view.View.measure(View.java:22071)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:22071)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
at android.view.View.measure(View.java:22071)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:806)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
at android.view.View.measure(View.java:22071)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:22071)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:806)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
at android.view.View.measure(View.java:22071)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6602)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:724)
at android.view.View.measure(View.java:22071)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2422)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1504)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1761)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1392)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6752)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at org.robolectric.shadows.ShadowMessageQueue.dispatchMessage(ShadowMessageQueue.java:148)
at org.robolectric.shadows.ShadowMessageQueue.access$200(ShadowMessageQueue.java:38)
at org.robolectric.shadows.ShadowMessageQueue$1.run(ShadowMessageQueue.java:126)
at org.robolectric.util.Scheduler$ScheduledRunnable.run(Scheduler.java:386)
at org.robolectric.util.Scheduler.runOneTask(Scheduler.java:278)
at org.robolectric.util.Scheduler.advanceTo(Scheduler.java:260)
at org.robolectric.util.Scheduler.advanceBy(Scheduler.java:243)
at org.robolectric.util.Scheduler.advanceBy(Scheduler.java:233)
at org.robolectric.util.Scheduler.setIdleState(Scheduler.java:88)
at org.robolectric.util.Scheduler.unPause(Scheduler.java:123)
at org.robolectric.shadows.ShadowLooper.unPause(ShadowLooper.java:347)
at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:398)
at org.robolectric.android.controller.ActivityController.visible(ActivityController.java:161)
ap...@google.com <ap...@google.com> #4
Project: platform/frameworks/support
Branch: androidx-master-dev
commit eb154034645a875304797a38995baac5ddd3346d
Author: Jeremy Woods <jbwoods@google.com>
Date: Tue Jan 14 12:40:54 2020
Avoid try/catching exceptions in FragmentPagerAdapters
When FragmentPagerAdapter or FragmentStatePagerAdapter
runs finishUpdate() in response to a measure/layout
pass, it runs commitNowAllowingStateLoss() as all
normal devices don't do measure/layout while processing
pending FragmentTransactions, but Robolectric will. In
order to ensure that Robolectric continued to work,
b/137201343 provided behavior to fallback to
commitAllowingStateLoss() when processing pending
FragmentTransactions. It used a try/catch for
IllegalStateExceptions, which means valid exceptions
could be ignored.
This change drops any transactions that attempt to be
committed while the FragmentManager is already executing
transactions.
Test: FragmentPagerAdapterRoboTest
Fixes: 147359544
Change-Id: I21ebbfe67d349980003b6df77704f005e693e664
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentPagerAdapter.java
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentStatePagerAdapter.java
A fragment/fragment/src/test/java/androidx/fragment/app/FragmentPagerActivity.kt
A fragment/fragment/src/test/java/androidx/fragment/app/FragmentPagerAdapterRoboTest.kt
https://android-review.googlesource.com/1208711
Branch: androidx-master-dev
commit eb154034645a875304797a38995baac5ddd3346d
Author: Jeremy Woods <jbwoods@google.com>
Date: Tue Jan 14 12:40:54 2020
Avoid try/catching exceptions in FragmentPagerAdapters
When FragmentPagerAdapter or FragmentStatePagerAdapter
runs finishUpdate() in response to a measure/layout
pass, it runs commitNowAllowingStateLoss() as all
normal devices don't do measure/layout while processing
pending FragmentTransactions, but Robolectric will. In
order to ensure that Robolectric continued to work,
commitAllowingStateLoss() when processing pending
FragmentTransactions. It used a try/catch for
IllegalStateExceptions, which means valid exceptions
could be ignored.
This change drops any transactions that attempt to be
committed while the FragmentManager is already executing
transactions.
Test: FragmentPagerAdapterRoboTest
Fixes: 147359544
Change-Id: I21ebbfe67d349980003b6df77704f005e693e664
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentPagerAdapter.java
M fragment/fragment/src/main/java/androidx/fragment/app/FragmentStatePagerAdapter.java
A fragment/fragment/src/test/java/androidx/fragment/app/FragmentPagerActivity.kt
A fragment/fragment/src/test/java/androidx/fragment/app/FragmentPagerAdapterRoboTest.kt
Description
Version used: 1.2.0-alpha01
When running a test in Robolectric, the new behavior introduced in
We should continue to use commitNowAllowingStateLoss(), but catch the IllegalStateException and fall back to commitAllowingStateLoss() specifically in the case where we're already performing transactions.