在android上保持应用程序状态
我在保存应用程序的状态/单例时遇到问题 当应用程序启动时,将显示一个加载屏幕(活动),并使用来自webservice调用的值初始化一个单例(请注意,网络访问不能在主线程上运行) 创建单例后,我打开我的主活动。请注意,构建布局需要来自单例的值 现在假设应用程序在后台运行,并在后台被终止(例如,由于内存不足)。我的singleton实例在应用程序被终止时被删除。当我切换回我的应用程序时,它会尝试重新创建主活动。正如我前面提到的,构建布局需要来自singleton的值,因此这会导致NullPointerException(当我尝试访问singleton的成员时,因为它不再存在) 我能告诉android在应用程序被杀后启动第一次加载活动吗?如果我可以在重新创建布局之前刷新singleton,那就太好了,但这似乎是一个问题,因为网络调用不能在主线程上,因此在刷新完成之前不会阻塞。 我假设我可以在上面的所有活动中保存单例并在onCreate方法中重新创建它,但这似乎有点不可预测,可能会导致不一致的状态 另一种方法可能是总是在桌面上完成我的活动,但这会导致丢失用户最后一个标签等等,即使应用程序没有被杀死,所以这不是一个好的选择在android上保持应用程序状态,android,Android,我在保存应用程序的状态/单例时遇到问题 当应用程序启动时,将显示一个加载屏幕(活动),并使用来自webservice调用的值初始化一个单例(请注意,网络访问不能在主线程上运行) 创建单例后,我打开我的主活动。请注意,构建布局需要来自单例的值 现在假设应用程序在后台运行,并在后台被终止(例如,由于内存不足)。我的singleton实例在应用程序被终止时被删除。当我切换回我的应用程序时,它会尝试重新创建主活动。正如我前面提到的,构建布局需要来自singleton的值,因此这会导致NullPointe
有没有办法解决这个问题 对于类似的东西,我使用伪singelton对象作为类。此对象将在开始时创建,并将保存在内存中。但请注意,如果其他应用程序需要内存,系统将终止该应用程序。然而,即使所有活动暂时终止,该对象也是持久的 要使用它,您需要在android清单中声明如下:
<application android:label="@string/app_name"
android:icon="@drawable/icon"
android:description="@string/desc"
android:name=".MySingeltonClass"
...
这两个函数的调用方式如下:
((MySingeltonClass)getApplicationContext()).informClientOnline();
当在活动中被调用时,您可以保存您的Singleton。您所需要做的就是实现它(这是Androids自己的序列化形式),然后您可以将它放入活动中的
outState
捆绑包中onSaveInstanceState()
,这将允许您在活动中的onCreate()
或onRestoreInstanceState()
中检索它,无论您喜欢哪种方式
我为您提供了一个示例:
public class TestActivity extends Activity {
private MySingleton singleton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState.containsKey("singleton")) {
singleton = savedInstanceState.getParcelable("singleton");
} else {
singleton = MySingleton.getInstance(5);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("singleton", singleton);
}
public static class MySingleton implements Parcelable {
private static MySingleton instance;
private int myData;
private MySingleton(int data) {
myData = data;
}
public static MySingleton getInstance(int initdata) {
if(instance == null) {
instance = new MySingleton(initdata);
}
return instance;
}
public static final Parcelable.Creator<MySingleton> CREATOR = new Creator<TestActivity.MySingleton>() {
@Override
public MySingleton[] newArray(int size) {
return new MySingleton[size];
}
@Override
public MySingleton createFromParcel(Parcel source) {
return new MySingleton(source.readInt());
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(myData);
}
}
}
公共类测试活动扩展活动{
私家侦探迈辛格尔顿·辛格尔顿;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
if(savedInstanceState.containsKey(“单例”)){
singleton=savedInstanceState.getParcelable(“singleton”);
}否则{
singleton=MySingleton.getInstance(5);
}
}
@凌驾
SaveInstanceState上受保护的无效(束超出状态){
super.onSaveInstanceState(超出状态);
突出。可放置(“单体”,单体);
}
公共静态类MySingleton实现了Parcelable{
私有静态MySingleton实例;
私有数据;
私人迈辛格尔顿(int数据){
myData=数据;
}
公共静态MySingleton getInstance(int initdata){
if(实例==null){
instance=new MySingleton(initdata);
}
返回实例;
}
公共静态最终包裹。创建者=新创建者(){
@凌驾
public MySingleton[]新数组(整数大小){
返回新的MySingleton[size];
}
@凌驾
公共MySingleton createFromParcel(地块源){
返回新的MySingleton(source.readInt());
}
};
@凌驾
公共int描述内容(){
返回0;
}
@凌驾
公共无效writeToParcel(Parcel-Parcel,int标志){
包裹写入(myData);
}
}
}
为什么不使用SharedReferences而不是singleton
任何时候,只要您想保存一些全局状态,就将其提交到首选项。只要您想读取全局状态,就可以从首选项中将其读回
这样,您就不必担心应用程序的生命周期,因为无论手机在做什么,您的数据都将始终被保留。显示代码或至少是代码片段。同时显示“崩溃”的日志——我们不能确定你说的是否是“…导致崩溃…”。问题不是崩溃,问题是当应用程序在后台被杀死时,singleton对象为空,当我切换回它时,它尝试加载最后一个活动,该活动必须访问singleton以创建其布局“系统将终止”部分正是我的问题,因为我需要一种方法在那之后重新创建对象。我的解决方案是在ondestroy中调用oncreate一个here-am-I方法和一个good-by方法…我将添加一个示例。谢谢,但是我不知道这如何帮助恢复我的singleton(好的,我想你的意思是我的singleton应该就是这个应用程序对象。现在请注意,数据必须用webservice调用填充。应用程序将被关闭,重新打开,应用程序对象将被创建,我可以安排我的webservice调用,但是我的活动被打开,调用没有完成,我的布局不好)。即使暂时关闭了所有活动,应用程序对象也将存在。这就是为什么我手动检查并保存shutdown()中的所有自定义状态
method。如果没有通知您应用程序已被终止,您如何手动检查并保存任何内容?可能我没有得到某些信息或某些信息仍然丢失…那么多个活动会发生什么情况?我猜单例将独立保存/序列化(可能不同
public class TestActivity extends Activity {
private MySingleton singleton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState.containsKey("singleton")) {
singleton = savedInstanceState.getParcelable("singleton");
} else {
singleton = MySingleton.getInstance(5);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("singleton", singleton);
}
public static class MySingleton implements Parcelable {
private static MySingleton instance;
private int myData;
private MySingleton(int data) {
myData = data;
}
public static MySingleton getInstance(int initdata) {
if(instance == null) {
instance = new MySingleton(initdata);
}
return instance;
}
public static final Parcelable.Creator<MySingleton> CREATOR = new Creator<TestActivity.MySingleton>() {
@Override
public MySingleton[] newArray(int size) {
return new MySingleton[size];
}
@Override
public MySingleton createFromParcel(Parcel source) {
return new MySingleton(source.readInt());
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(myData);
}
}
}