Skip to content

fix memory leak #14127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a78654c
fix memory leak
yk3372 May 23, 2017
694487b
Update Colors.md
May 23, 2017
2aa8eba
Update Accessibility.md
May 23, 2017
cc653fb
Add @format to a few files
cpojer May 23, 2017
3e6f86e
Properly mock `path` in DependencyGraph-test
cpojer May 23, 2017
35e1397
Minor lint fixes
cpojer May 23, 2017
cf24d4c
Add Prop type for View
mjmahone May 23, 2017
acbbfc3
packager: add missing dep
May 23, 2017
2f28373
Create an `OutputFn` that can build indexed RAM bundles
davidaurelio May 23, 2017
0cf80fd
Simplify `File` type: `map` is nullable, but not optional
davidaurelio May 23, 2017
cf7f33d
Covariant properties for `ModuleTransportLike`
davidaurelio May 23, 2017
5afb3ed
Use `ModuleTransportLike` only with `$ReadOnlyArray`
davidaurelio May 23, 2017
83c9fa2
Update Getting Started, Upgrading for CRNA
hramos May 23, 2017
730df65
Add viewIsDescendantOf for UIManager on Android
Swordsman-Inaction May 23, 2017
92fc282
Fixing potential measure call with negative size value
May 23, 2017
7c42b69
packager: ResolutionRequest: use _loadAsFile from _loadAsDir
May 23, 2017
a038f2f
packager: ResolutionRequest: refactor _loadAsDir and dependents
May 23, 2017
996bbe1
Expand Getting Started, Debugging, Running on Device guides.
hramos May 23, 2017
b1ae29b
Move packager launcher scripts outside of `packager/`
davidaurelio May 23, 2017
4334cfe
Fix DependencyGraph-test in OS.
cpojer May 23, 2017
75916c1
Reinstate RCTDeviceEventEmitter section for Android docs
May 23, 2017
aac33ce
ESLint: Upgrade to 3.19.0
yungsters May 23, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Libraries/Components/AppleTV/TVViewPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,14 @@ var TVViewPropTypes = {

};

export type TVViewProps = {
isTVSelectable?: bool,
hasTVPreferredFocus?: bool,
tvParallaxProperties?: Object,
tvParallaxShiftDistanceX?: number,
tvParallaxShiftDistanceY?: number,
tvParallaxTiltAngle?: number,
tvParallaxMagnification?: number,
};

module.exports = TVViewPropTypes;
9 changes: 6 additions & 3 deletions Libraries/Components/View/View.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,29 @@
const NativeMethodsMixin = require('NativeMethodsMixin');
const NativeModules = require('NativeModules');
const Platform = require('Platform');
const React = require('React');
const PropTypes = require('prop-types');
const React = require('React');
const ReactNativeFeatureFlags = require('ReactNativeFeatureFlags');
const ReactNativeStyleAttributes = require('ReactNativeStyleAttributes');
const ReactNativeViewAttributes = require('ReactNativeViewAttributes');
const ViewPropTypes = require('ViewPropTypes');

const invariant = require('fbjs/lib/invariant');
const requireNativeComponent = require('requireNativeComponent');
const warning = require('fbjs/lib/warning');

const {
AccessibilityComponentTypes,
AccessibilityTraits,
} = require('ViewAccessibility');

const requireNativeComponent = require('requireNativeComponent');

const forceTouchAvailable = (NativeModules.PlatformConstants &&
NativeModules.PlatformConstants.forceTouchAvailable) || false;

import type {ViewProps} from 'ViewPropTypes';

export type Props = ViewProps;

/**
* The most fundamental component for building a UI, `View` is a container that supports layout with
* [flexbox](docs/flexbox.html), [style](docs/style.html),
Expand Down
41 changes: 41 additions & 0 deletions Libraries/Components/View/ViewPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,49 @@ if (Platform.isTVOS) {
TVViewPropTypes = require('TVViewPropTypes');
}

import type {
AccessibilityComponentType,
AccessibilityTrait,
} from 'ViewAccessibility';
import type {EdgeInsetsProp} from 'EdgeInsetsPropType';
import type {TVViewProps} from 'TVViewPropTypes';

const stylePropType = StyleSheetPropType(ViewStylePropTypes);

// There's no easy way to create a different type if(Platform.isTVOS):
// so we must include TVViewProps
export type ViewProps = {
accessible?: bool,
accessibilityLabel?: React$PropType$Primitive<any>,
accessibilityComponentType?: AccessibilityComponentType,
accessibilityLiveRegion?: 'none' | 'polite' | 'assertive',
importantForAccessibility?: 'auto'| 'yes'| 'no'| 'no-hide-descendants',
accessibilityTraits?: AccessibilityTrait | Array<AccessibilityTrait>,
accessibilityViewIsModal?: bool,
onAccessibilityTap?: Function,
onMagicTap?: Function,
testID?: string,
nativeID?: string,
onResponderGrant?: Function,
onResponderMove?: Function,
onResponderReject?: Function,
onResponderRelease?: Function,
onResponderTerminate?: Function,
onResponderTerminationRequest?: Function,
onStartShouldSetResponder?: Function,
onStartShouldSetResponderCapture?: Function,
onMoveShouldSetResponder?: Function,
onMoveShouldSetResponderCapture?: Function,
hitSlop?: EdgeInsetsProp,
pointerEvents?: 'box-none'| 'none'| 'box-only'| 'auto',
style?: stylePropType,
removeClippedSubviews?: bool,
renderToHardwareTextureAndroid?: bool,
shouldRasterizeIOS?: bool,
collapsable?: bool,
needsOffscreenAlphaCompositing?: bool,
} & TVViewProps;

module.exports = {
...TVViewPropTypes,

Expand Down
11 changes: 9 additions & 2 deletions Libraries/StyleSheet/EdgeInsetsPropType.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,22 @@
*/
'use strict';

var {PropTypes} = require('React');

var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker');

var {PropTypes} = require('React');

var EdgeInsetsPropType = createStrictShapeTypeChecker({
top: PropTypes.number,
left: PropTypes.number,
bottom: PropTypes.number,
right: PropTypes.number,
});

export type EdgeInsetsProp = {
top: number,
left: number,
bottom: number,
right: number,
};

module.exports = EdgeInsetsPropType;
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Note that you'll need the Android NDK installed, see [prerequisites](https://git
```bash
./gradlew :Examples:Movies:android:app:installDebug
# Start the packager in a separate shell (make sure you ran npm install):
./packager/packager.sh
./scripts/packager.sh
# Open the Movies app in your emulator
```

Expand Down
4 changes: 2 additions & 2 deletions RNTester/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Start an Android emulator ([Genymotion](https://www.genymotion.com) is recommend

cd react-native
./gradlew :RNTester:android:app:installDebug
./packager/packager.sh
./scripts/packager.sh

_Note: Building for the first time can take a while._

Expand All @@ -46,7 +46,7 @@ Run the following commands from the react-native folder:
./gradlew :ReactAndroid:packageReactNdkLibsForBuck
buck fetch rntester
buck install -r rntester
./packager/packager.sh
./scripts/packager.sh

_Note: The native libs are still built using gradle. Full build with buck is coming soon(tm)._

Expand Down
4 changes: 2 additions & 2 deletions RNTester/RNTester.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1439,7 +1439,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=node\n$SRCROOT/../packager/react-native-xcode.sh RNTester/js/RNTesterApp.ios.js";
shellScript = "export NODE_BINARY=node\n$SRCROOT/../scripts/react-native-xcode.sh RNTester/js/RNTesterApp.ios.js";
};
68CD48B71D2BCB2C007E06A9 /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
Expand All @@ -1453,7 +1453,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=node\n$SRCROOT/../packager/react-native-xcode.sh RNTester/js/RNTesterApp.ios.js";
shellScript = "export NODE_BINARY=node\n$SRCROOT/../scripts/react-native-xcode.sh RNTester/js/RNTesterApp.ios.js";
};
/* End PBXShellScriptBuildPhase section */

Expand Down
4 changes: 2 additions & 2 deletions RNTester/RNTesterLegacy.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1432,7 +1432,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=node\n$SRCROOT/../packager/react-native-xcode.sh RNTester/js/RNTesterApp.ios.js";
shellScript = "export NODE_BINARY=node\n$SRCROOT/../scripts/react-native-xcode.sh RNTester/js/RNTesterApp.ios.js";
};
68CD48B71D2BCB2C007E06A9 /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
Expand All @@ -1446,7 +1446,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=node\n$SRCROOT/../packager/react-native-xcode.sh RNTester/js/RNTesterApp.ios.js";
shellScript = "export NODE_BINARY=node\n$SRCROOT/../scripts/react-native-xcode.sh RNTester/js/RNTesterApp.ios.js";
};
/* End PBXShellScriptBuildPhase section */

Expand Down
4 changes: 2 additions & 2 deletions React/React.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3335,7 +3335,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost 8081 ; then\n if ! curl -s \"http://localhost:8081/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port 8081 already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../packager/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi";
shellScript = "if [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost 8081 ; then\n if ! curl -s \"http://localhost:8081/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port 8081 already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi";
showEnvVarsInLog = 0;
};
142C4F7F1B582EA6001F0B58 /* Include RCTJSCProfiler */ = {
Expand Down Expand Up @@ -3394,7 +3394,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\nif nc -w 5 -z localhost 8081 ; then\nif ! curl -s \"http://localhost:8081/status\" | grep -q \"packager-status:running\" ; then\necho \"Port 8081 already in use, packager is either not running or not running correctly\"\nexit 2\nfi\nelse\nopen \"$SRCROOT/../packager/launchPackager.command\" || echo \"Can't start packager automatically\"\nfi\nfi";
shellScript = "if [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\nif nc -w 5 -z localhost 8081 ; then\nif ! curl -s \"http://localhost:8081/status\" | grep -q \"packager-status:running\" ; then\necho \"Port 8081 already in use, packager is either not running or not running correctly\"\nexit 2\nfi\nelse\nopen \"$SRCROOT/../scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\nfi\nfi";
showEnvVarsInLog = 0;
};
3D383D3E1EBD27B9005632C8 /* Install Third Party */ = {
Expand Down
4 changes: 2 additions & 2 deletions React/ReactLegacy.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2398,7 +2398,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost 8081 ; then\n if ! curl -s \"http://localhost:8081/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port 8081 already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../packager/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi";
shellScript = "if [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost 8081 ; then\n if ! curl -s \"http://localhost:8081/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port 8081 already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi";
showEnvVarsInLog = 0;
};
142C4F7F1B582EA6001F0B58 /* Include RCTJSCProfiler */ = {
Expand Down Expand Up @@ -2443,7 +2443,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\nif nc -w 5 -z localhost 8081 ; then\nif ! curl -s \"http://localhost:8081/status\" | grep -q \"packager-status:running\" ; then\necho \"Port 8081 already in use, packager is either not running or not running correctly\"\nexit 2\nfi\nelse\nopen \"$SRCROOT/../packager/launchPackager.command\" || echo \"Can't start packager automatically\"\nfi\nfi";
shellScript = "if [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\nif nc -w 5 -z localhost 8081 ; then\nif ! curl -s \"http://localhost:8081/status\" | grep -q \"packager-status:running\" ; then\necho \"Port 8081 already in use, packager is either not running or not running correctly\"\nexit 2\nfi\nelse\nopen \"$SRCROOT/../scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\nfi\nfi";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.queue.MessageQueueThread;
import com.facebook.react.bridge.queue.MessageQueueThreadRegistry;
import com.facebook.react.bridge.queue.QueueThreadExceptionHandler;
import com.facebook.react.bridge.queue.ReactQueueConfiguration;
import com.facebook.react.bridge.queue.ReactQueueConfigurationImpl;
import com.facebook.react.bridge.queue.ReactQueueConfigurationSpec;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.uimanager.ViewManagerPropertyUpdater;
import com.facebook.soloader.SoLoader;
import com.facebook.systrace.Systrace;
import com.facebook.systrace.TraceListener;
Expand Down Expand Up @@ -297,6 +299,9 @@ public void run() {
}
});

MessageQueueThreadRegistry.clear();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What MessageQueueThread is associated with the UI thread? I don't think this does anything.

ViewManagerPropertyUpdater.clear();

// This is a noop if the listener was not yet registered.
Systrace.unregisterListener(mTraceListener);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,9 @@ public static MessageQueueThread myMessageQueueThread() {
sMyMessageQueueThread.get(),
"This thread doesn't have a MessageQueueThread registered to it!");
}

public static void clear() {
sMyMessageQueueThread.remove();
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,23 @@ public final int getTotalNativeChildren() {
return mTotalNativeChildren;
}

public boolean isDescendantOf(ReactShadowNode ancestorNode) {
ReactShadowNode parentNode = getParent();

boolean isDescendant = false;

while (parentNode != null) {
if (parentNode == ancestorNode) {
isDescendant = true;
break;
} else {
parentNode = parentNode.getParent();
}
}

return isDescendant;
}

/**
* Returns the offset within the native children owned by all layout-only nodes in the subtree
* rooted at this node for the given child. Put another way, this returns the number of native
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,22 @@ public void findSubviewIn(int reactTag, float targetX, float targetY, Callback c
mOperationsQueue.enqueueFindTargetForTouch(reactTag, targetX, targetY, callback);
}

/**
* Check if the first shadow node is the descendant of the second shadow node
*/
public void viewIsDescendantOf(
final int reactTag,
final int ancestorReactTag,
final Callback callback) {
ReactShadowNode node = mShadowNodeRegistry.getNode(reactTag);
ReactShadowNode ancestorNode = mShadowNodeRegistry.getNode(ancestorReactTag);
if (node == null || ancestorNode == null) {
callback.invoke(false);
return;
}
callback.invoke(node.isDescendantOf(ancestorNode));
}

/**
* Determines the location on screen, width, and height of the given view relative to the root
* view and returns the values via an async callback.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,17 @@ public void findSubviewIn(
callback);
}

/**
* Check if the first shadow node is the descendant of the second shadow node
*/
@ReactMethod
public void viewIsDescendantOf(
final int reactTag,
final int ancestorReactTag,
final Callback callback) {
mUIImplementation.viewIsDescendantOf(reactTag, ancestorReactTag, callback);
}

/**
* Registers a new Animation that can then be added to a View using {@link #addAnimation}.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ public interface ShadowNodeSetter<T extends ReactShadowNode> extends Settable {
new HashMap<>();
private static final Map<Class<?>, ShadowNodeSetter<?>> SHADOW_NODE_SETTER_MAP = new HashMap<>();

public static void clear() {
ViewManagersPropertyCache.clear();
VIEW_MANAGER_SETTER_MAP.clear();
SHADOW_NODE_SETTER_MAP.clear();
}

public static <T extends ViewManager, V extends View> void updateProps(
T manager,
V v,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
private static final Map<Class, Map<String, PropSetter>> CLASS_PROPS_CACHE = new HashMap<>();
private static final Map<String, PropSetter> EMPTY_PROPS_MAP = new HashMap<>();

public static void clear() {
CLASS_PROPS_CACHE.clear();
EMPTY_PROPS_MAP.clear();
}

/*package*/ static abstract class PropSetter {

protected final String mPropName;
Expand Down
9 changes: 7 additions & 2 deletions ReactCommon/yoga/yoga/Yoga.c
Original file line number Diff line number Diff line change
Expand Up @@ -1736,8 +1736,13 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions(const YGNodeRef node,
const float marginAxisRow = YGNodeMarginForAxis(node, YGFlexDirectionRow, availableWidth);
const float marginAxisColumn = YGNodeMarginForAxis(node, YGFlexDirectionColumn, availableWidth);

const float innerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;
const float innerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn;
// We want to make sure we don't call measure with negative size
const float innerWidth = YGFloatIsUndefined(availableWidth)
? availableWidth
: fmaxf(0, availableWidth - marginAxisRow - paddingAndBorderAxisRow);
const float innerHeight = YGFloatIsUndefined(availableHeight)
? availableHeight
: fmaxf(0, availableHeight - marginAxisColumn - paddingAndBorderAxisColumn);

if (widthMeasureMode == YGMeasureModeExactly && heightMeasureMode == YGMeasureModeExactly) {
// Don't bother sizing the text if both dimensions are already defined.
Expand Down
2 changes: 1 addition & 1 deletion docs/Accessibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ In the above example we've created a custom radio button that now behaves like a

## Testing VoiceOver Support (iOS)

To enable VoiceOver, go to the Settings app on your iOS device. Tap General, then Accessibility. There you will find many tools that people use to use to make their devices more usable, such as bolder text, increased contrast, and VoiceOver.
To enable VoiceOver, go to the Settings app on your iOS device. Tap General, then Accessibility. There you will find many tools that people use to make their devices more usable, such as bolder text, increased contrast, and VoiceOver.

To enable VoiceOver, tap on VoiceOver under "Vision" and toggle the switch that appears at the top.

Expand Down
2 changes: 1 addition & 1 deletion docs/Colors.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ next: platform-specific-code
previous: images
---

Components in React Native are [styled using JavaScript](docs/styles.html). Color properties usually match how [CSS works on the web](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value).
Components in React Native are [styled using JavaScript](docs/style.html). Color properties usually match how [CSS works on the web](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value).

### Red-green-blue

Expand Down
Loading