很长一段时间以来,我遇到了将变量从一个Activity传递到另一个Activity的麻烦,而且我通常不得不解决一些非常丑陋的静态类黑客攻击才能使它工作。
一般来说,我使用Activity的类型调用静态方法,以及Activity需要的变量。这些存储在一个静态变量中,并在所述活动的构造函数中检索。
像我说的那样,非常难看。并且没有“myActivity.StartActivity(new Activity);”这样的东西。 StartActivity的所有重载都采用Intent或typeof(MyOtherActivity)。所以我的问题是,我是否完全误解了活动的概念,或者我只是错过了一种向他们传递参数的完全明显的方法?
@Edit:我想传递对象的实际引用而不仅仅是对象副本的原因是因为我试图将一个View Model从一个覆盖的Activity传递到新的Activity。当然,对此视图模型所做的任何更改都应该反映在父活动上,只有当两个活动的视图模型指向同一个实例时才能实现。
我正在使用Xamarin.Android编写应用程序,但C#和Java之间的代码几乎相同,所以这两种语言的答案都很好。
答案 0 :(得分:6)
问题是Android可以随时终止托管您应用的进程(如果它在后台)。当用户返回到您的应用程序时,Android将创建一个新进程来托管您的应用程序,并将在堆栈顶部重新创建Activity
。为此,Android会保留Intent
的“序列化”版本,以便重新创建Intent
以将其传递给Activity
。这就是Intent
中所有“额外内容”必须为Parcelable
或Serializable
的原因。
这也是您无法传递对象引用的原因。当Android重新创建进程时,这些对象都不会再存在。
要考虑的另一点是不同的活动可能在不同的流程中运行。即使来自同一应用程序的活动也可能在不同的进程中(如果清单指定了这一点)。由于对象引用不适用于进程边界,因此这是您无法将引用传递给Intent
中对象的另一个原因。
答案 1 :(得分:0)
您还可以使用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
calss上执行此操作,因为在App启动时调用此类,因此您不必手动启动它。
请记住,作用于Application
的变量的生命周期范围通过扩展名应用于应用程序
如果Android
认为有必要,则此类将为Garbage Collected,因此您必须修改代码以包含此案例。
您可以使用SharedPreferences
或Database
保存变量,以防它们被删除,并从App类中检索它们以获得更快的结果。
调查您需要将哪些信息保存为应用程序范围的状态,以及可以直接从数据库中检索哪些信息。两者都有成本影响,您需要确保平衡。
并且不要忘记在OnStop
和OnDestroy
上根据需要发布资源
我很少使用意图,我觉得这样更好。