以下是重现错误的过程。
在我的项目v0.29中发生,但我刚刚在v0.33上测试了一个新的,并且它的行为方式相同。
当应用程序运行时,按下设备/模拟器的主页按钮并通过单击桌面图标打开应用程序,这里发生的是应用程序重新启动安装组件而没有先卸载它,导致如果你多次这样做,应用程序会运行几个实例。
然后,如果您按下设备后退按钮,它将终止并卸载顶级实例,让您使用前一个实例,直到卸下最后一个实例,它将转到桌面。
在此之后如果您退出应用程序,就像您最初按下主页按钮并通过单击桌面图标打开它,这不会重新启动应用程序再次安装它,从这一刻开始正常运行。 同样,如果应用程序首次启动,则使用后退按钮将其退出,之后主页按钮将表现正常。
同样以同样的方式,如果你实现像react-native-activity-android这样的软件包,以避免在按下后退按钮时杀死应用程序,你最终会运行多个应用程序。
我不知道android,当应用程序被杀死时发生了什么事情,如果你使用home按钮将应用程序发送到后台它可以正常工作?
任何想法如何解决这个问题,所以将应用程序发送到后台并重新打开它并不会挂载多个应用程序?
如果我需要在后台运行应用程序以进行位置/通知,假设我无法解决此问题,但我可以处理事件监听器,因此它们不会被执行多次。性能/内存同时安装多个应用程序有多糟糕?
由于
答案 0 :(得分:8)
此错误是由于React Native为每个应用程序创建了多个活动,导致多个根组件同时运行。
似乎适用于大多数人的解决方案是将launchMode
设置为singleInstance
AndroidManifest.xml
,如下所示:
<manifest>
...
<application>
...
<activity ... android:launchMode="singleInstance">
</activity>
</application>
</manifest>
更多信息:
答案 1 :(得分:1)
事实证明,使用BackAndroid并从后台处理程序返回false
会导致组件卸载。当应用程序返回到前台时,需要重建这些组件。
我已尝试将android:launchMode="singleTask"
添加到AndroidManifest.xml
中的活动,但无济于事。我的解决方案是使用react-native-activity-android,然后根据需要将应用放在后台ActivityAndroid.moveTaskToBack()
,而不是return false
。您的处理程序将看起来像这样:
handleBackPress() {
if (this.navigator) {
if (this.navigator.getCurrentRoutes().length > 1) {
this.navigator.pop();
} else {
ActivityAndroid.moveTaskToBack();
}
}
return true;
};
注意:此插件的作者尚未更新它以与React Native 0.29.0或更高版本兼容。在撰写本文时,我的pull request要解决此问题。
答案 2 :(得分:1)
实际上,您可以实现自己的模块来解决此问题。这很简单。将这段代码添加到您的本机模块中。
@ReactMethod
public void moveTaskToBack(Callback cb) {
Activity activity = getCurrentActivity();
boolean wasMoved = activity.moveTaskToBack(true);
if (cb != null) {
cb.invoke(wasMoved);
}
}
然后你可以像Ryan提出的那样处理onBackPress事件。始终返回true并在需要时调用moveTaskToBack()。