使用Android Application类来保存数据

Dav*_*ave 109 android application-lifecycle

我正在开发一个相当复杂的Android应用程序,它需要关于应用程序的大量数据(我说总共大约500KB - 这对于移动设备来说是否很大?).据我所知,应用程序中的任何方向更改(在活动中,更准确地说)会导致活动的完全破坏和重新创建.根据我的发现,Application类没有相同的生命周期(即,所有意图和目的,它总是被实例化).将状态信息存储在应用程序类中然后从Activity引用它是否有意义,或者由于移动设备上的内存限制,这通常不是"可接受的"方法?我真的很感激有关这个主题的任何建议.谢谢!

Bry*_*nny 132

我认为500kb不会是那么大的交易.

你所描述的正是我如何解决我在活动中丢失数据的问题.我在Application类中创建了一个全局单例,并且能够从我使用的活动中访问它.

如果将要使用很多,您可以在Global Singleton中传递数据.

public class YourApplication extends Application 
{     
     public SomeDataClass data = new SomeDataClass();
}
Run Code Online (Sandbox Code Playgroud)

然后在以下任何活动中调用它:

YourApplication appState = ((YourApplication)this.getApplication());
appState.data.UseAGetterOrSetterHere(); // Do whatever you need to with the data here.
Run Code Online (Sandbox Code Playgroud)

在我的博客文章 "Global Singleton"一节中讨论它.


Vit*_*nko 57

那些指望Application实例的人是错的.一开始,Application只要整个应用程序进程存在,它就好像存在一样,但这是一个不正确的假设.

操作系统可能会根据需要终止进程.所有流程分为5个级别的"killability" ,在doc中指定.

因此,例如,如果您的应用由于用户接听来电而进入后台,那么根据RAM的状态,操作系统可能(或可能不)杀死您的进程(Application在此过程中销毁实例) .

我认为更好的方法是将您的数据保存到内部存储文件,然后在您的活动恢复时读取它.

更新:

我得到了很多负面反馈,所以是时候加上澄清了.:)好吧,最初我真的使用了一个错误的假设,即状态对应用程序非常重要.但是,如果您的应用程序没问题,有时状态会丢失(可能是某些图像只会重新读取/重新加载),那么将其保留为成员就完全可以Application.

  • 这对我们的制作来说是一个不可思议的惊喜.相信我杀死Android的过程,它只取决于RAM状态和文档中描述的其他因素.这对我们来说是一场噩梦,所以我只是分享我的真实经历.好吧,我们在模拟器上没有这个,但在现实世界中,一些设备"应用"过载,因此杀死后台进程是正常情况.是的,如果用户然后决定将应用程序放到前台 - 操作系统将恢复其堆栈,包括"应用程序"实例,但是除非您坚持使用,否则不会有您依赖的静态数据. (14认同)
  • 如果申请被杀,那么谁在乎,对吧?申请已经不见了.据我了解,Android将回收包含活动等内存的进程.如果包含应用程序的进程被终止(如果Android甚至会这样做?),那就像杀死应用程序一样.用户需要再次启动应用程序,此时,谁在乎?这是该应用程序的新实例. (13认同)
  • 我想我可能会采用混合方法.我已经知道了覆盖方向变化的明显技巧(具有其他好处).由于应用程序是游戏,我不确定在启动之间保持数据是否"足够"; 虽然它可能不会非常困难,因为大多数数据都可以序列化(尽管我不想在每个方向更改之间序列化和反序列化).我非常感谢输入.我不会说那些依赖于App实例的是"错误的".很大程度上取决于应用:). (2认同)
  • 我有大约1mb数据,结构复杂.当设备超负荷工作时,序列化/反序列化可能花费我2-3秒.在活动之间保存/加载的想法花费了太多时间.我使用应用程序作为存储.当然,我存储在应用程序实例中的数据类检查了每个元数据 - 数据是否仍然存活或必须加载.所以Dave必须:1.提供加载/保存完成2.保持应用程序中的数据.3.用于访问数据的三重检查逻辑. (2认同)

sax*_*xos 6

如果要访问活动之外的"Global Singleton"并且不希望Context通过所有涉及的对象来获取单例,则可以在应用程序类中定义静态属性,该属性包含对本身.只需初始化onCreate()方法中的属性即可.

例如:

public class ApplicationController extends Application {
    private static ApplicationController _appCtrl;

    public static ApplicationController getAppCtrl()
    {
         return _appCtrl;
    }
}
Run Code Online (Sandbox Code Playgroud)

因为子类Application也可以获取资源,所以只需在定义静态方法时就可以访问它们,返回它们,如:

public static Resources getAppResources()
{
    return _appCtrl.getResources();
}
Run Code Online (Sandbox Code Playgroud)

但是在传递Context引用时要非常小心,以避免内存泄漏.

  • 您忘了注意,您必须在清单中为要实例化的类添加android:name =".ApplicationController"xml属性应用程序标记. (6认同)