在Android活动之间高效传递自定义对象数据 [Mono Android]

7
我已经被这个问题困扰了一段时间。 我正在开发一个Android应用程序,用于存储人们的钓鱼记录、喜欢的钓鱼地点、渔具箱清单和其他数据。我的所有类都是可序列化的,并且可以在活动之间保存和加载,目前似乎运行良好。但是随着越来越多的数据被存储,我预测该应用程序将开始变慢。
我基本上想问的是是否有任何方法可以在整个应用程序中保留此数据,以便在新屏幕弹出时无需每次加载它。我已经找到了以下信息来帮助解决,但需要更加清晰易懂:
另一个论坛说你可以把它放在Application对象中:
[Application]
public class MyApp : Android.App.Application {
    public MyApp(IntPtr handle)
        : base (handle)
    {
    }

    public FishingData Data {get; set;}
}

然后在你的Activity内部:

((MyApp) this.ApplicationContext).Data = value;

我以前从未听说过这种方法,而且我不确定这种方法能否通过整个应用程序的流程(我觉得无论如何都必须通过序列化加载数据)。以下是我希望应用程序执行的操作:

第一个活动是主菜单,当屏幕加载时,需要执行以下操作:

  1. 如果找到设置文件,则使用序列化加载以前的FishingData对象(我知道如何做到这一点)
  2. 如果没有找到设置文件,则创建一个新的干净的FishingData对象以备后用(我也知道如何做到这一点)
  3. 现在我们有了一个FishingData对象,如何确保我不必在每个活动中重复步骤1-2。我如何将FishingData对象传递给下一个活动,并确保它在应用程序仍在运行时全局存在。我只想通过序列化加载一次(<--我不知道如何做到这一点),并且仅在用户向此对象添加数据时保存它(我知道如何做到这一点)。

任何帮助都将不胜感激。这让我很困扰,我似乎无法解决这个问题。这似乎是一个常见的事情,但我没有找到任何详细的信息。


我不知道,但是给你一个+1,因为这是一个非常好格式化的第一个问题。欢迎来到StackOverflow。 - Phillip Schmidt
为了在活动之间传递信息,您需要使用Parcelable http://developer.android.com/reference/android/os/Parcelable.html。然而,为了保存所有这些数据,最好至少创建一个sqllite数据库,或者更理想的是使用您自己的数据库。 - Jameo
请查看http://forums.xamarin.com/discussion/451/communicate-with-iserializable。 - Cheesebaron
2个回答

3

以下是我如何通过Parcelable在应用程序中传递数据的方式。假设你有一个名为Fisherman(基本上是用户)的类。

public class Fisherman implements Parcelable {
 private String name;
 private Tacklebox box;
 public int describeContents() {
     return 0;
 }

 public void writeToParcel(Parcel out, int flags) {
     out.writeString(name);
     out.writeParcelable(box, 0);
 }

 public static final Parcelable.Creator<Fisherman> CREATOR
         = new Parcelable.Creator<Fisherman>() {
     public Fisherman createFromParcel(Parcel in) {
         return new Fisherman(in);
     }

     public Fisherman[] newArray(int size) {
         return new Fisherman[size];
     }
 };

 private Fisherman(Parcel in) {
     name = in.readString();
     box = in.readParcelable(com.fisher.Tacklebox);
 }
}

在这个例子中,你需要为每个数据模型定义可序列化(parcelable)。比如说,如果你有一个包含另一个对象叫作 tacklebox 的渔夫对象,你也需要为 tacklebox 定义可序列化,如果你想要继续嵌套模型,也需要依次定义。这样,你只需要使用可序列化对象在活动(activity)之间传递数据就行了。
Intent intent = new Intent(this, Activity.class);
intent.putParcelableExtra("com.fisher.Fisherman", fisherman);

读取

Bundle b = getIntent().getExtras();
Fisherman fisher = b.getParcelable("com.fisher.Fisherman");

很遗憾,我只能回答你问题中的第三步。我建议将你的三个步骤分别提出来作为一个问题,因为你要做的事情比一个问题稍微有点长。

1

您可以使用这种方法,只要您的Application对象存在(这意味着它将贯穿整个应用程序和活动),它就会一直存在。您可以在此处阅读有关在Application对象中存储全局变量的更多信息here。我认为mono不会影响您使用此方法。


谢谢,我使用上面链接中的步骤进行了测试,现在成功地在各个活动中保留了全局变量。感谢您的帮助,这让我感到非常轻松。 - TeamChillshot
很高兴能帮上忙 :) 请将问题标记为已解决:http://stackoverflow.com/faq#howtoask - Jong
1
应用程序对象保证在所有活动之前创建,并保持到所有活动被销毁。不过,你不能将其用作全局状态,因为当你的应用程序在后台运行时,Android 可以销毁所有活动和应用程序对象。 - Jared Kells
1
如果您接到电话或切换应用程序,这可能意味着启动浏览器意图,操作系统可以选择销毁所有活动、销毁您的应用程序对象并终止您的托管进程。当您结束电话通话时,将启动一个新进程,创建一个新的应用程序对象和一个新的活动。您将获得的唯一状态将在onCreate中传递的bundle中。所有静态变量都将为空,您的应用程序对象将是全新的实例。 - Jared Kells

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接