我无法保存应用程序的状态/单例。
当应用程序启动时,会显示一个加载屏幕(活动),并使用来自Web服务调用的值初始化单例(请注意,网络访问不能在主线程上运行)。
创建单身人士后,我打开我的主要活动。请注意,构建布局需要单例中的值。
现在假设应用程序进入后台并在那里被杀死(例如由于内存不足)。应用程序被杀死时,我的单例实例被删除。当我切换回我的应用程序时,它会尝试重新创建主要活动。正如我前面提到的,构建布局需要单例的值,因此这会导致NullPointerException(当我尝试访问单例的成员时,因为它不再存在)。
我可以以某种方式告诉android在应用程序被杀后启动第一个加载活动吗?如果我可以在重新创建布局之前刷新单例,那将是很好的,但这似乎是一个问题,因为网络调用不能在主线程上,因此在刷新完成之前不会阻塞。 我假设我可以在onStop的所有活动中保存单例并在onCreate方法中重新创建它,但这似乎有点太不可预测,可能会导致状态不一致...
另一种方法可能就是总是在onStop上完成我的活动,但是这会导致丢失用户最后的标签,依此类推,即使应用程序没有被杀死,所以这不是一个好的选择。
关于如何解决这个问题的任何想法?
答案 0 :(得分:4)
为什么不使用SharedPreferences而不是单身?
只要您想保存某些全局状态,请将其提交到首选项。无论何时您想要读取全局状态,请从首选项中读取它。
然后您根本不必关心应用程序生命周期,因为无论手机在做什么,您的数据都将始终保留。
答案 1 :(得分:0)
对于类似的东西,我使用伪singelton对象作为Application类。此对象将在开头创建,并将在内存中。但请注意,如果其他应用程序需要内存,系统将终止应用程序。然而,即使所有活动都暂时终止,这个目标仍然是持久的。
要使用它,你需要在你的Android清单中声明,如:
<application android:label="@string/app_name"
android:icon="@drawable/icon"
android:description="@string/desc"
android:name=".MySingeltonClass"
...
这是一个代码示例:
public abstract class MySingeltonClass extends Application {
// ...
public void informClientOnline() {
clientOnline=true;
Log.v(LOG_TAG, "Client is online!");
}
public void informClientShutdown() {
clientOnline=false;
Log.v(LOG_TAG, "Client is going offline. Waiting for restart...");
Timer t=new Timer("shutdowntimer", false);
t.schedule(new TimerTask() {
@Override
public void run() {
if(!clientOnline) {
Log.v(LOG_TAG, "Client has not restartet! Shutting down framework.");
shutdown();
System.exit(0);
}
}
}, 5000);
}
}
这两个函数的调用方式如下:
((MySingeltonClass)getApplicationContext()).informClientOnline();
答案 2 :(得分:0)
您可以在调用Activity中的onSaveInstanceState()
时保存您的Singleton。您需要做的就是让它实现Parcelable
(它是Androids自己的序列化形式),然后您可以将它放在outState
中的Bundle
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);
}
}
}