2012-10-26 111 views
3

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

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

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

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

我可以告诉android在应用程序被杀后启动第一个加载活动吗?如果我可以在重新创建布局之前刷新单身人士,那将是一件好事,但这似乎是一个问题,因为网络调用不能在主线程上,因此在刷新完成之前不会阻塞。 我认为我可以在onStop的所有活动中保存单例并在onCreate方法中重新创建它,但是这看起来有点太不可预测,并且可能导致状态不一致在onStop上完成我的活动,但是这会导致失去用户上一次的选项卡等等,即使应用程序没有被杀死,所以这不是一个好的选择。

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

+0

显示代码或至少代码片段。同时显示'崩溃'的logcat - 如果你所说的是“......导致崩溃......”,我们不能真正地这样做。 – Squonk

+1

问题不是崩溃,问题是单例对象为空,因为应用程序在后台被终止,当我切换回它时,它尝试加载最后一个活动,该活动必须访问单例以创建其布局。 – Tim

回答

3

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

无论何时您想保存一些全局状态,请将其提交到首选项。无论何时您想要阅读全局状态,请从首选项中读取它。

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

+0

这一定会做,我会评估这个明天,并提供反馈如果它适用于我:)我非常喜欢不必处理应用程序生命周期的想法 – Tim

+0

SharedPreferences不是通用实用程序。在我的情况下,我有10万个结构化的数据和图像。通过SharedPreferences保存/加载不是goos的想法 - 我试过了,但加载需要10秒。 – Kostadin

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(); 
+0

“系统将终止”部分正是我的问题,因为我需要一种方式来重新创建对象。 – Tim

+0

我的解决方案是在ondestroy上调用oncreate一个*这里是我*方法和* by *方法...我将添加一个示例。 – rekire

+0

@Tim我加了一个例子。 – rekire

0

当Activity被调用时,你可以保存你的单身人士。所有你需要做的就是让它实现Parcelable(这是Androids自己的序列化形式),那么你可以把它放在outStateBundle,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); 
     } 

    } 

} 
+0

那么多个活动会发生什么?我猜这个singleton会被独立保存/序列化(可能有不同的值),并且每个onCreate都会将我的单例更改为不同的东西(这会导致不一致的状态) – Tim

+0

如果每个活动中的单身人员不能处于不同的状态一个真正的单身人士。它到处都是同一个对象,这就是为什么它是一个单身人士:) –

+0

是的,但如果我序列化我的单身我有点“冻结”它,对吧?现在假设一个活动打开一个只在短时间内打开的活动(如对话框)。在这个对话类活动关闭之后,它会保存它的状态,对吧?现在十分钟后主要活动保存其状态(10分钟后状态)。应用程序被杀后恢复生机,主要活动将恢复单身人士。但是当对话回来时它会重新提前10分钟的状态,是不是? – Tim

相关问题