是否有可能通过引用将对象从一个活动传递到下一个活动,最好的策略是什么?
我有一个简单的 Android 应用程序,它使用类的实例(我们称之为 DataManager),以类似 Façade 的方式管理对域类的访问。我最初将其设计为可以使用静态方法检索的单例,但最终我对实现的混乱感到恼火,并重构为我认为更简单、更清晰的想法。
现在的想法是,对于每个打开的文件,创建一个DataManager
,它们处理文件I/O 和域类的修改(例如Book
)。当启动一个新的 Activity 时,我将这个实例作为 Serialized
extra 传递(我还没有开始使用 Parcelable
,但希望当我有了基本的概念工作),然后我从新 Activity 的 onCreate()
方法中的 Intent
获取 DataManager
。
然而,对象的比较表明从一个 Activity 发送的对象与从第二个 Activity 中的 Bundle
检索的对象不同(不同的引用)。阅读 Bundle
(在 StackOverflow 等)上表明,Bundle 除了按值传递之外不能执行任何操作。
那么在“活动”之间传递对象的最干净、最安全的策略是什么?正如我所见,我可以
忘记通过引用传递,并接受每个
Activity
都有自己的DataManager对象的情况。每次关闭活动时都会传回新的 DataManager ,以便底层活动可以使用它。 (我认为这是一个简单的解决方案。)回到使用单例
DataManager
并使用静态方法从每个Activity
获取它。 (不热衷于再次使用单例。)扩展应用程序以创建对
DataManager
的全局引用。 (再次强调,不热衷于全局变量的想法。)
这是一个公平的总结吗?我可以使用其他一些健康的策略吗?
I have a simple Android application that uses an instance of a class, let's call it DataManager
, to manage access to the domain classes in a Façade-like way. I initially designed it as a singleton which could be retrieved using static methods but I eventually got irritated with the messiness of my implementation and refactored to what I reckoned was a simpler and cleaner idea.
Now the idea is that for each file that is opened, one DataManager
is created, which they handles both file I/O and modification of the domain classes (e.g. Book
). When starting a new Activity, I pass this one instance as a Serializable
extra (I haven't got on to using Parcelable
yet, but expect I will when I have the basic concept working), and then I grab the DataManager
from the Intent
in the onCreate()
method of the new Activity.
Yet comparison of the objects indicates that the object sent from one activity is not identical (different references) to the object retrieved from the Bundle
in the second Activity. Reading up on Bundle
(on StackOverflow, etc.) suggests that Bundles cannot do anything other than pass-by-value.
So what is likely to be the cleanest and safest strategy for passing an object between Activities? As I see it I could
Forget about passing by reference and live with each
Activity
having its own DataManager object. Pass back the newDataManager
every time I close an activity so that the underlying activity can use it. (The simple solution, I think.)Go back to using a singleton
DataManager
and use a static method to get it from eachActivity
. (Not keen on using singletons again.)Extend Application to create a sort of global reference to
DataManager
. (Again, not keen on the idea of globals.)
Is that a fair summary? Is there some other healthy strategy I could use?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
另一种方法是创建服务。第一个活动将启动服务并绑定到它,当您启动新意图时,取消绑定第一个活动,当第二个活动启动时,绑定到服务。
这样您就不必停止服务或担心在活动之间传递数据。
Another approach would be to create a service. The first activity would start the service and bind to it, when you launch a new intent, unbind the first activity and when second activity starts, bind to the service.
This way you don't have to ever stop the service or worry about passing data between activities.
Java 没有按引用传递,因此该选项已失效,我建议依赖注入在活动之间传递数据。否则,单例肯定是正确的选择。
Java does not have pass by reference so that option is out, I would suggest dependency injection for passing data between the activities. Otherwise definetely the singleton would be the way to go.
规定的一个是通过实现Parcellable接口,这是在Activity之间传递对象的方式。第二个也是更好的选择是创建一个Singleton来确保它的单个对象。
The prescribed one is Going by implementing Parcellable interface, thats the way to pass Objects between Activities.. and the 2nd and better choice is to make a Singleton to be sure its single Object.
将 DataManager 创建为实现 Service 的单例。将服务绑定到清单 xml 中的应用程序(请参阅链接),您将拥有一个持久的单例,您的活动可以毫无问题地访问。
如果您需要获取大量数据,传递可分割参数很快就会变得非常混乱。单例方法虽然通常被认为是一种反模式,但在这些情况下却很有魅力。请记住不要创建多个相互交互的单例。
Create your DataManager as a Singleton that implements Service. Bind the service to your application in the manifest xml (see the link), and you will have a persistent singleton your activities can access without issues.
Passing parcellable arguments can quickly get very messy if you need to get a lot of data. The singleton approach, although usually considered an anti-pattern, works like a charm in cases like these. Just remember to not create multiple singletons that interact with one another.
我建议使用应用程序子类。它允许您保存对 DataManger 类的单个引用,并且只要您的应用程序存在,它就会持续存在。
具有静态字段的单例也可以工作,但是文档中的某些地方说静态字段的内容不是存储数据的安全位置。据我了解,只要您的类加载器保留在内存中,静态字段就应该持续存在。因此,只有当整个进程离开内存时,单例才会消失,在这种情况下,应用程序类也会离开内存,但它会调用应用程序的 onDestroy 方法,这使您能够安全地关闭 DataManager 并将重要数据保存到记忆。
这就是你的两个变体。
Android 的方法是让你的 DataManager 成为 ContentProvider 。这将使您可以从每个活动访问您的数据,而无需持有全局引用。我不确定如何构建一个保留在内存中并且不会经常重新实例化的缓存内容提供程序。
I would suggest using an Application Subclass. It allows you to hold a single reference to the DataManger class and is persistent as long as your app lives.
A singleton with a static field will also work, but there are some place in the documentation where it says that the content of static fields is not a safe place to store your data. As I understand static fields should persist as long as your ClassLoader stays in memory. Therefore a singleton should only vanish if the whole process leaves the memory and in that case the application class will also leave the memory, but it will call the onDestroy methods of the Application and that enables you to safely close your DataManager and persist important data to memory.
That said to your two variations.
The Android way to go would be to make your DataManager a ContentProvider. This will make it possible to access your Data from every Activity without holding a global reference. I'm not sure how you would build a caching Content Provider that stays in memory and is not reinstantiated too often.