相当长一段时间以来,我在将变量从一个 Activity 传递到另一个 Activity 时遇到了麻烦,而且我通常不得不解决一些非常丑陋的静态类黑客才能使其工作。
通常类似于我使用活动类型以及活动所需的变量调用的静态方法。这些被存储在静态变量中,并在所述活动的构造函数中检索。
就像我说的,非常丑陋。并且不存在“myActivity.StartActivity(new Activity);”这样的东西。 StartActivity 的所有重载都采用 Intent 或 typeof(MyOtherActivity)。
所以我的问题是,我是否完全误解了活动的概念,或者我只是缺少一种完全明显的方式来向它们传递参数?
@编辑:我想要传递对对象的实际引用,而不是简单地传递对象的副本,是因为我试图将视图模型从覆盖的 Activity 传递到新的 Activity。当然,对此视图模型所做的任何更改都应该反映在父活动上,这只有在两个活动的视图模型指向同一实例时才可能实现。
我正在使用 Xamarin.Android 编写应用程序,但 C# 和 Java 之间的代码几乎相同,因此使用这两种语言的答案都可以。
问题是 Android 可以随时终止托管您的应用程序的进程(如果它在后台)。当用户返回到您的应用程序时,Android 将创建一个新进程来托管您的应用程序,并在堆栈顶部重新创建
Activity
。为了做到这一点,Android 保留了 Intent
的“序列化”版本,以便它可以重新创建 Intent
将其传递给 Activity
。这就是为什么 Intent
中的所有“额外内容”都需要是 Parcelable
或 Serializable
。
这也是为什么不能传递对象的引用的原因。当 Android 重新创建进程时,这些对象将不再存在。
另一点需要考虑的是不同的活动可能在不同的进程中运行。即使来自同一应用程序的活动也可能位于不同的进程中(如果清单指定了这一点)。由于对象引用不能跨进程边界工作,这是您无法在
Intent
中传递对对象的引用的另一个原因。
您还可以使用 Application 类全局存储对象并检索它们:
using Android.Runtime;
namespace SomeName
{
[Application]
public class App : Application
{
public string Name { get; set;}
public App (IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
public override void OnCreate ()
{
base.OnCreate ();
Name = "";
}
}
}
您可以通过以下方式访问数据:
App application = (App)Application.Context;
application.Name = "something";
我选择在
Application
类上执行此操作,因为此类在应用程序启动时调用,因此您不必手动启动它。Application
的变量的生命周期范围也扩展为应用程序。Android
认为有必要,则此类将被垃圾收集,因此您必须修改代码以也包含这种情况。SharedPreferences
或 Database
保存变量,以防它们被删除,并从 App 类中检索它们以获得更快的结果。
不过,在使用这种方法时不要过度浪费,因为在此类上附加太多信息可能会导致性能下降。仅添加您知道应用程序的不同部分需要的信息,并且检索该信息的成本超过将其存储为应用程序变量的成本。
调查您需要将哪些信息保存为应用程序范围的状态,以及哪些信息可以直接从数据库中检索。两者都会产生成本影响,您需要确保取得正确的平衡。
并且不要忘记根据需要释放资源
OnStop
和 OnDestroy
Android 开发者设置有“强制终止活动”选项,这将有助于测试此场景。