4

我无法保存我的应用程序的状态/单例。

当应用程序启动时,会显示一个加载屏幕(活动),并使用来自 web 服务调用的值初始化一个单例(请注意,网络访问不能在主线程上运行)。

创建单例后,我打开我的主要活动。请注意,构建布局需要来自单例的值。

现在假设应用程序进入后台并在那里被杀死(例如,因为内存不足)。当应用程序被杀死时,我的单例实例被删除。当我切换回我的应用程序时,它会尝试重新创建主要活动。正如我之前提到的,构建布局需要来自单例的值,因此这会导致 NullPointerException(当我尝试访问单例的成员时,因为它不再存在)。

我可以以某种方式告诉android在应用程序被杀死后开始第一个加载活动吗?如果我可以在重新创建布局之前刷新单例,那就太好了,但这似乎是一个问题,因为网络调用不能在主线程上,因此在刷新完成之前不会阻塞。我假设我可以在所有活动 onStop 中保存单例并在 onCreate 方法中重新创建它,但这似乎有点太不可预测并且可能会导致状态不一致......

另一种方法可能是始终在 onStop 上完成我的活动,但这会导致丢失用户最后在哪个选项卡上等等,即使应用程序没有被杀死,所以这不是一个好的选择。

关于如何解决这个问题的任何想法?

4

3 回答 3

4

为什么不直接使用 SharedPreferences 而不是单例?

每当您想保存一些全局状态时,请将其提交给首选项。每当您想读取全局状态时,请从首选项中读取它。

然后,您根本不必担心应用程序的生命周期,因为无论手机在做什么,您的数据都将始终被保留。

于 2012-10-26T21:39:09.570 回答
0

对于类似的事情,我使用了一个伪单点对象作为应用程序类。该对象将在开始时创建,并将在内存中。但请注意,如果其他应用程序需要内存,系统将终止该应用程序。然而,即使所有活动都暂时终止,此对象也是持久的。

要使用它,您需要在您的 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();
于 2012-10-26T21:06:16.853 回答
0

onSaveInstanceState()在 Activity 被调用时,您可以保存您的 Singleton 。您需要做的就是使其实现Parcelable(它是 Android 自己的序列化形式),然后您可以将其放入outState Bundle其中,您可以根据需要在 Activity 中或Activity 中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);
        }

    }

}
于 2012-10-26T21:14:23.713 回答