[英]Memory Leak in React Native Android App using setTimeout
我有一个 React Native Android 电视应用程序,用于在电视上显示数字标牌内容。 在应用程序运行大约一个小时后,我收到了几个 outOfMemory 异常。 我的应用程序最初呈现一个使用setTimeout
每 1 秒运行一次的Player
组件。 每一秒,该组件都会遍历一个 JSON 数组,该数组包含有关不同图像或视频的信息。 根据几个条件, Player
组件将更新currentAsset
值 currentAsset 并重新渲染Asset
组件,显示视频或图像指定的秒数。 为了重现currentAsset
异常,我使 currentAsset 的值每 1 秒从自动播放视频到图像来回切换,因此它实际上在屏幕上显示图像一秒钟,然后是视频并无限重复。 虽然这不是典型用法,但它是我能够重新创建 memory 异常的最快方法。
这是我的骨架代码:
class Player extends Component {
constructor(props) {
super(props)
this.currentAsset = null
this.state = { currentAsset: null }
}
componentDidMount(){
//create cache directory initializes file caching for the player
createCacheDirectory().then(() => {
this.play()
})
}
poll = () => {
//conditional here to either poll an API for updates and call play or just call play
if(canCallAPI){
//this condition happens every 30 seconds
//might call setState in a promise which also saves files locally to the device.
callAPI().then(() => {
//some other setup stuff here
play();
})
}
play()
}
play = () => {
//there is more logic here but the idea is that I get a new object containing a file/video path which I pass to the `Asset` Component
this.currentAsset = this.getCurrentAssetFromJSONArray();
this.setState({ currentAsset: this.currentAsset });
this.timeout = setTimeout(this.poll, 1000);
}
render() {
return (<Asset asset={this.state.currentAsset} />);
}
end
Asset
组件非常简单,只检查this.state.currentAsset.file_type
的值并根据当前文件类型呈现<Image />
或<Video />
。
有一个 memory 泄漏,因为每次组件重新渲染它都会创建一个新的计时器实例而不清除以前的实例。
我们需要在组件卸载时清除计时器。
class Player extends Component {
constructor(props) {
super(props);
this.currentAsset = null;
this.state = { currentAsset: null };
this.timeout = null;
}
componentDidMount() {
//create cache directory initializes file caching for the player
createCacheDirectory().then(() => {
this.play();
});
}
poll = () => {
//conditional here to either poll an API for updates and call play or just call play
if (canCallAPI) {
//this condition happens every 30 seconds
//might call setState in a promise which also saves files locally to the device.
callAPI().then(() => {
//some other setup stuff here
play();
});
}
play();
};
play = () => {
//there is more logic here but the idea is that I get a new object containing a file/video path which I pass to the `Asset` Component
this.currentAsset = this.getCurrentAssetFromJSONArray();
this.setState({ currentAsset: this.currentAsset });
this.timeout = setTimeout(this.poll, 1000);
};
componentWillUnmount() {
// Clear current timeout when component unmount
if (this.timeout) {
clearTimeout(this.timer);
}
}
render() {
return <Asset asset={this.state.currentAsset} />;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.