From 8fbce3099dca2340eaa614e9a90bb89a4a386bb9 Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Wed, 11 May 2016 17:15:08 -0700 Subject: [PATCH] Fix RefreshControl race condition Summary: There was a race condition with `SwipeRefreshLayout` that cause the `RefreshControl` to keep refreshing when it shouldn't. It was caused because we have to use `post` to set the refreshing state otherwise it doesn't work when setting `refreshing=true` on initial mount. What happened is that `post` doesn't guarantee the order the runnables will be called so calling post with `refreshing=true` followed by `refreshing=false` caused the `resfreshing=false` runnable to be called before the `resfreshing=true` one. This made it stay in refreshing state when it should not. ``` D/test ( 6171): setRefreshing true W/ReactNativeJS( 6171): false D/test ( 6171): setRefreshing false D/test ( 6171): setRefreshing post false D/test ( 6171): setRefreshing post true ``` This change adds an instance variable and uses it in the `post` runnable to make sure the last set value is always used. **Test plan (required)** Tested that it fixed the issue in the [original issue app](https://github.com/digisqu Closes https://github.com/facebook/react-native/pull/7317 Differential Revision: D3290464 Pulled By: andreicoman11 fbshipit-source-id: 15cabcfc6d2f191443be96e8845b924ce66c369f --- .../swiperefresh/ReactSwipeRefreshLayout.java | 17 +++++++++++++++++ .../swiperefresh/SwipeRefreshLayoutManager.java | 11 ++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout.java b/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout.java index f458c0ab06b914..728def66f7940b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/ReactSwipeRefreshLayout.java @@ -20,10 +20,27 @@ */ public class ReactSwipeRefreshLayout extends SwipeRefreshLayout { + private boolean mRefreshing = false; + public ReactSwipeRefreshLayout(ReactContext reactContext) { super(reactContext); } + @Override + public void setRefreshing(boolean refreshing) { + if (mRefreshing != refreshing) { + mRefreshing = refreshing; + // Use `post` otherwise the control won't start refreshing if refreshing is true when + // the component gets mounted. + post(new Runnable() { + @Override + public void run() { + ReactSwipeRefreshLayout.super.setRefreshing(mRefreshing); + } + }); + } + } + @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (super.onInterceptTouchEvent(ev)) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.java index 5db04a1a77f39c..e66132ff735d90 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/SwipeRefreshLayoutManager.java @@ -74,15 +74,8 @@ public void setSize(ReactSwipeRefreshLayout view, int size) { } @ReactProp(name = "refreshing") - public void setRefreshing(final ReactSwipeRefreshLayout view, final boolean refreshing) { - // Use `post` otherwise the control won't start refreshing if refreshing is true when - // the component gets mounted. - view.post(new Runnable() { - @Override - public void run() { - view.setRefreshing(refreshing); - } - }); + public void setRefreshing(ReactSwipeRefreshLayout view, boolean refreshing) { + view.setRefreshing(refreshing); } @ReactProp(name = "progressViewOffset", defaultFloat = 0)