Synchronize ProgressBar constructors

Summary: If a ProgressBar is created on the shadow thread (for measurement) at the same time one is created on the UI thread, we hit a race condition which sometimes results in a crash (##java.lang.NullPointerException: Null pointer exception during instruction 'invoke-static {v5}, android.animation.AnimatorSet$Node android.animation.AnimatorSet$Node.access$200(android.animation.AnimatorSet$Node) // method@153'##). This diff synchronizes the ctors.

Reviewed By: foghina

Differential Revision: D3151037

fb-gh-sync-id: 8ed96d6debdc1a5fa2f9bd037bfb75def25be3e8
fbshipit-source-id: 8ed96d6debdc1a5fa2f9bd037bfb75def25be3e8
This commit is contained in:
Andy Street 2016-04-07 13:10:56 -07:00 committed by Facebook Github Bot 9
parent e4865a5609
commit b9396cd744
3 changed files with 18 additions and 2 deletions

View File

@ -31,7 +31,7 @@ import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
public void setStyle(@Nullable String styleName) {
int style = ReactProgressBarViewManager.getStyleFromString(styleName);
mProgressBar = new ProgressBar(getContext(), null, style);
mProgressBar = ReactProgressBarViewManager.createProgressBar(getContext(), style);
mProgressBar.setMax(MAX_PROGRESS);
removeAllViews();
addView(

View File

@ -61,7 +61,7 @@ public class ProgressBarShadowNode extends LayoutShadowNode implements CSSNode.M
MeasureOutput measureOutput) {
final int style = ReactProgressBarViewManager.getStyleFromString(getStyle());
if (!mMeasured.contains(style)) {
ProgressBar progressBar = new ProgressBar(getThemedContext(), null, style);
ProgressBar progressBar = ReactProgressBarViewManager.createProgressBar(getThemedContext(), style);
final int spec = View.MeasureSpec.makeMeasureSpec(
ViewGroup.LayoutParams.WRAP_CONTENT,
View.MeasureSpec.UNSPECIFIED);

View File

@ -11,6 +11,9 @@ package com.facebook.react.views.progressbar;
import javax.annotation.Nullable;
import android.content.Context;
import android.widget.ProgressBar;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.uimanager.BaseViewManager;
import com.facebook.react.uimanager.annotations.ReactProp;
@ -33,6 +36,19 @@ public class ReactProgressBarViewManager extends
/* package */ static final String REACT_CLASS = "AndroidProgressBar";
/* package */ static final String DEFAULT_STYLE = "Normal";
private static Object sProgressBarCtorLock = new Object();
/**
* We create ProgressBars on both the UI and shadow threads. There is a race condition in the
* ProgressBar constructor that may cause crashes when two ProgressBars are constructed at the
* same time on two different threads. This static ctor wrapper protects against that.
*/
public static ProgressBar createProgressBar(Context context, int style) {
synchronized (sProgressBarCtorLock) {
return new ProgressBar(context, null, style);
}
}
@Override
public String getName() {
return REACT_CLASS;