2016-11-16 74 views
1

我有一个Activity创建一个保留的片段,以便在长时间运行操作期间活动经历任何配置更改的情况下保留长时间运行的网络操作。所以基本上我试图使用保留的Fragment,就像一个Singleton一样,直到Activity的onDestroy()被调用。在onCreate()被调用之前在Android上设置数据保留片段

我的目标是让Activity的onCreate()触发长时间运行的网络操作,因为我只希望它在活动创建时运行而不是每次重新启动(否则我会将它放在onStart())。

为此,我首先在Activity的onCreate中创建一个保留的片段,然后使用FragmentManager添加保留的片段,然后在Activity的onCreate方法中启动网络调用,并将网络对象传递给保留的片段以保存。

这是有效的,但是我很担心,因为如果我记录发生了什么,我可以看到Activity首先在保留的Fragment上设置数据,然后调用保留的Fragment的onCreate()方法。这看起来不正确,看起来不符合要求,但它有效。

在片段运行onCreate()方法之前利用保留的Fragment实例是不好的做法吗?

编辑 阅读的答复,并想多一点之后,我意识到,启动从活动的onCreate()虽然方便了网络电话,是有风险的事情。正如在回复中指出的那样,长时间运行的操作很可能会很快返回,并试图操作尚未初始化的活动视图。所以对于我的具体情况,我正在从Activity的onStart()方法开始长时间运行的操作,然后使用retainFragment缓存响应。这样,即使onStart()被多次调用并尝试再次启动长时间运行的操作,第一次尝试的结果也会被缓存并返回。

+1

您可以将单独的服务中的长网络操作分开,并且只需从onCreate调用服务 – Pooya

+0

服务是一种解决方案,但对于我所尝试的东西来说,它们看起来很沉重为了完成一项服务,您需要实现某种事件总线来传回结果或绑定到服务,以便您可以直接与它进行通信,我试图避免这种情况。我试图解决的问题是启动一个异步操作,该操作相对快速完成,但允许足够的时间进行配置更改(如旋转设备)。 – neonDion

+0

网络操作应该在UI线程以外的线程上运行,所以要么使用AsyncTask要么使用服务。因为每次旋转设备时onCreate都会调用,所以会运行一个新实例。但对于服务,它将在后台运行,并且您可以通过共享首选项和共享首选筛选器与服务进行通信。 – Pooya

回答

2

我会承认这是不寻常的,但我想不出一个理由为什么它会是坏的。保留片段的优点是对片段的引用不会被破坏,因此保留的引用也被保留。在片段的整个生命周期内(分别添加和删除片段时),调用一次onCreate()onDestroy()

危险可能是异步操作在调用onCreate()之前完成。同样,在调用onDestroy()之后并且您希望Fragment正在运行时,操作可能会结束。有一些方法,如Fragment#setArguments(),可以在生命周期的某些部分中调用而不是。如果您希望Fragment正在运行时调用这些方法,那么您将得到抛出的异常。所以你最终不得不投入一堆像if(isAttached()) { /* do this */ }这样的支票。将操作放入onCreate()将确保至少在操作完成前至少开始

但是,如果您实际上不依赖任何功能,那么它应该没问题。生命周期只是为了告诉你它发生了什么。

1

只要你不是靠活动/片段的观点是可用的,而片段的onCreate,你将被罚款:

注意的是,虽然片段的活动仍处于被该过程中可以被称为创建。因此,您不能依赖于此时正在初始化活动的内容视图层次结构。

https://developer.android.com/reference/android/app/Fragment.html#onCreate(android.os.Bundle)

不过,你需要确保可能的边缘情况下长时间运行的操作可以活动之前完成和片段被完全创建(如果你依靠自己的观点,这可能是一个问题) 因此,请考虑长时间运行完成后需要执行的操作,并且结果需要在某处显示。

相关问题