【问题标题】:How the best way to fix: Can not perform this action after onSaveInstanceState?如何最好的解决方法:onSaveInstanceState 后无法执行此操作?
【发布时间】:2017-03-18 14:26:06
【问题描述】:

我有 10 个活动。我还有20个碎片。

他们每个人都使用 UI。如果在调用方法 onSaveInstanceState() 之后使用 UI(例如,在最小化应用程序之后)则抛出异常:在 onSaveInstanceState 之后无法执行此操作

为了解决这个问题,我检查每个片段和活动是否应用程序可见性(我为此编写了自定义方法)。如果结果为真,则开始使用 UI。

好的,问题解决了。但我认为这不是最好的解决方案。

还有什么办法可以解决这个问题吗?

附:根框架和根活动不是很好的解决方案,因为逻辑会重复。

【问题讨论】:

  • 在什么情况下你会得到Can not perform this action after onSaveInstanceState
  • 当我尝试这样做时:fragmentTransaction.beginTransaction().replace(R.id.my_frag_cont, fragment).commit();
  • 查看这个问题的答案。他们对问题和可能的解决方案进行了解释。 stackoverflow.com/questions/7469082/…

标签: android


【解决方案1】:

此问题通常是您的应用架构存在更深层次问题的征兆。当视图层和业务逻辑层之间的关注点没有适当分离时,您往往会看到它。

我想你正在直接在 Activity/Fragment 中做一些异步工作,然后在结果返回时尝试做一个 Fragment Transaction。

你可以做很多事情来解决这个问题:

不要使用片段

几乎从不需要使用 Fragment - 90% 的情况下,您可以使用 ViewGroup 获得相同的结果,并避免 Fragment 导致的所有生命周期问题、随机崩溃和其他不稳定行为。

我只在需要特定生命周期回调 (onActivityResult) 或第三方库(Android Pay、Braintree)强制我使用 Fragment 时使用。

通过界面分离视图

这基本上就是 MVP/MVVM 模式的全部内容。它将您的视图与您的业务逻辑(Presenter/ViewModel)分开。这会对您有所帮助,因为您的 Activity/Fragment 将实现 View 接口:

public class MyActivity implements MyView { ...

当你的 Activity 开始时,它会绑定到 Presenter,当它完成时,它会解除绑定:

protected void onCreate(Bundle bundle) {
    // ...
    presenter.bind(this);
}

protected void onDestroy() {
    // ...
    presenter.unbind(this);
}

现在,当您的业务逻辑中的异步操作完成并尝试更新视图时,如果 Activity 已完成,则视图将被解除绑定。您可以对其进行空检查,或者(如我所愿)在其位置放置一个无操作视图。

不要从长期运行的异步操作中更新您的视图

尽可能不要直接根据长时间运行的异步进程(网络或繁重的计算)的结果来更新您的视图。而是将结果缓存在持久层(db/prefs/file)中。然后让您的视图从持久层订阅数据。

订阅可以通过多种方式完成 - RxJava、事件总线通知、静态回调。

这样,当结果返回时,它就会被保存。如果视图仍然处于活动状态,它会收到通知并从持久性中加载结果。如果没有,它可以在下次加载时从那里拾取它们。

终于

顺便说一句,您可以拨打.commitAllowingStateLoss() 而不是只拨打.commit(),它不会崩溃。不过,这并不能真正解决根本问题...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-18
    • 2014-03-05
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多