我有两个 Activity ;假设A和B。在activity A
中,注册了一个广播接收器,该广播接收器侦听将完成 Activity A的特定事件。我正在onCreate()
中注册该广播接收器,并在onDestroy()
的activity A
中销毁它。
为简单起见,在button
中有一个名为“销毁 Activity A”的activity B
。当用户单击button
时,activity A
应该被销毁。
通常,所有这些操作均正常运行,没有任何问题,但是在以下情况下会出现此问题:
1)假设我使用的是activity B
,然后按Home键将应用程序移至后台,那么如果我使用其他占用大量资源的应用程序,则Android系统将杀死我的应用程序以释放内存。然后,如果我从最近的任务中打开我的应用程序,将恢复activity B
,并调用onCreate()
,onResume()
等方法。现在,我按button
销毁activity A
,但是 Activity A已经被销毁,因此直到和除非我通过按activity A
进入onCreate()
,才会调用onResume()
的activity A
,back button
等方法。因此,broadcast receiver
未注册以侦听该事件。
2)当用户从设备设置的“开发人员”选项中选择“不保留 Activity ”时,也会出现同样的问题。
很长时间以来,我一直在寻找解决这个问题的方法,但是我找不到合适的答案。处理这种情况的最佳方法是什么?这是Android的错误吗?对于此问题应该有一些解决方案。
请帮我。
最佳答案
在保留当前广播逻辑的同时无法解决此问题。
从后端堆栈(imo)中杀死 Activity 不是正确的方法。您应该强烈考虑更改导航逻辑。
但是,如果您的项目很大并且时间很麻烦,那么重构就不可能了。的方法有效,但是您提到您有很多 Activity 需要杀死,他的解决方案实现起来非常棘手。
我的建议如下。这可能不是最好的主意,但我想不到另一个。所以也许可以帮上忙。
您应该具有以下条件:
ArrayList<String> activitiesToKill
对象。 (如果不扩展Application
,则可以将其作为静态变量首先,我们必须确保当操作系统杀死内存不足的应用程序时,
activitiesToKill
不会丢失。在BaseActivity
中,我们在onSaveInstanceState
期间保存列表,并将其恢复为onRestoreInstanceState
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("activitiesToKill", activitiesToKill);
}
private void onRestoreInstanceState(Bundle state) {
if (state != null) {
activitiesToKill = (ArrayList<String>) state.getSerializable("activitiesToKill");
super.onRestoreInstanceState(state);
}
}
这里的想法是通过使用 Activity 名称保存哪些 Activity 应在列表中被杀死。
逻辑如下:
假设您有 Activity A,B,C,D和E
在 Activity E中,按下按钮,然后想要杀死B和D
当您按E中的按钮时,会将B和D的名称添加到
activitiesToKill
对象。activitiesToKill.add(B.class.getSimpleName()
activitiesToKill.add(D.class.getSimpleName()
在BaseActivity的
onCreate
方法中,我们必须检查if(savedInstanceState != null)
{
//The activity is being restored. We check if the it is in the lest to Kill and we finish it
if(activitiesToKill.contains(this.getClass().getSimpleName()))
{
activitiesToKill.remove(this.getClass().getSimpleName())
finish();
}
}
如果 Activity 通过广播被杀死,请确保删除该 Activity 的名称。
所以基本上这是在每种情况下都会发生的事情。
如果应用程序正常运行,并且您单击按钮,则广播将被发送,并且B和D将被杀死。确保从
activitiesToKill
中删除B和D如果该应用程序被杀死并恢复,则按下按钮,广播将无效,但是您已将B和D添加到
activitiesToKill
对象中。因此,当您单击返回时,将创建 Activity ,并且saveInstanceState不为null,则 Activity 结束。这种方法认为 Activity E知道必须杀死哪些 Activity 。
如果您不知道从E中杀死哪些 Activity ,则必须稍微修改以下逻辑:
而不是使用ArrayList使用
HashMap<String, bool>
创建 Activity B后,它将自己注册到哈希图中:
activitiesToKill.put(this.class.getSimpleName(), false)
然后在 Activity E中,您要做的就是将所有条目设置为
true
然后,在基础 Activity 的创建时,您必须检查该 Activity 是否已在activityToKill中注册(哈希图包含键),并且 bool(boolean) 值是
true
,您将其杀死(不要忘记将其返回为false或删除键)这样可以确保每个 Activity 都向HashMap注册,而 Activity E并不是最了解要杀死的所有 Activity 。而且,别忘了删除它们,以防广播杀死它们。
这种方法还可以确保从意图中正常打开该 Activity 时不会杀死该 Activity ,因为在这种情况下,onSaveInstanceState在onCreate中将为null,因此不会发生任何事情。
如果您有需要通过不同条件终止的 Activity 组(不仅是单击按钮),则可以完成更高级的检查,以便可以使用HashMap的HashMap将它们划分为类别。
另请注意,如果您有多个具有相同名称但 bundle 包不同的 Activity ,则可以使用getName代替getSimpleName。
我希望我的脑子里写的很清楚,请告诉我是否有不清楚的地方。
祝你好运