2015-10-19 61 views
3

很长一段时间以来,我都遇到过将变量从一个活动传递给另一个活动的麻烦,而且我通常必须解决一些相当丑陋的静态类黑客才能使其工作。将活动意图的参考传递给

一般来说,我沿着一个静态方法的行来说明一下,我用Activity的类型以及Activity所需的变量来调用它。这些被存储在一个静态变量中,并在所述活动的构造函数中被检索。

就像我说的,挺丑的。并没有像“myActivity.StartActivity(新活动);”这样的东西。所有StartActivity的重载都采用Intent或typeof(MyOtherActivity)。

所以我的问题是,我完全误解了活动的概念,还是我简单地错过了一个完全明显的方法来传递参数给他们?

@编辑:我想传递一个对象的实际引用,而不是简单的对象的副本的原因是因为我试图从覆盖的活动传递一个视图模型,到新的活动。当然,对这个视图模型所做的任何更改都应该反映在父活动上,这只有在两个活动的视图模型指向相同的实例时才有可能。

我正在使用Xamarin.Android编写应用程序,但C#和Java之间的代码几乎完全相同,所以在这两种语言中的答案都很好。

+2

可能的重复http://stackoverflow.com/questions/2091465/how-do-i-pass-data-between-activities-in-android – dsharew

+0

部分属实。您提供的链接上的答案解答了如何将基本值类型(如整数和字符串)移动到单独的Activity,但不知道如何传递实际的引用对象,例如我自己的自定义类型的对象。 – Falgantil

+0

为你搜索它。 http://stackoverflow.com/questions/2736389/how-to-pass-object-from-one-activity-to-another-in-android – dsharew

回答

5

问题是,Android可以在任何时候杀死托管您的应用程序的进程(如果它在后台)。当用户返回到您的应用程序时,Android会创建一个新的进程来托管您的应用程序,并将在堆栈顶部重新创建Activity。为了做到这一点,Android保留了Intent的“序列化”版本,以便它可以重新创建Intent以将其传递给Activity。这就是为什么Intent中的所有“额外”都需要为ParcelableSerializable

这也是为什么你不能传递一个对象的引用。当Android重新创建过程时,这些对象都不再存在。

需要考虑的另一点是不同的活动可能在不同的过程中运行。即使来自同一个应用程序的活动可能在不同的过程中(如果清单指定了这一点)。由于对象引用不能跨越进程边界,所以这是为什么您无法将引用传递给Intent中的对象的另一个原因。

+0

从你所说的话来看,这听起来像是一个令人难以置信的不稳定的环境来制作应用程序,考虑到你永远不知道你的应用程序的哪个部分正在运行,因此难以创建导航流程,在退出和进入应用程序时不会中断再次在稍后的时间点。这是真的吗? – Falgantil

+0

是的,那是真的。这意味着您需要考虑到这一点构建您的应用程序。你不是第一个绊倒这个的Android开发者,你也不会是最后一个。 –

0

您还可以使用的应用类在全球范围内存储对象和检索它们:

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觉得有必要,则该类将被垃圾收集,因此您必须修改代码以包含此案例。
您可以使用SharedPreferencesDatabase保存您的变量以防它们被删除,并从App类中检索它们以获得更快的结果。

不要过分浪费你如何使用这种方法,因为在这个类上附加太多的信息可能会导致性能下降。只添加您知道应用程序不同部分所需的信息,以及检索该信息的成本超过将其存储为应用程序变量的成本。

调查您需要将哪些信息保存为应用程序广泛状态,以及可以直接从数据库中检索哪些信息。两者都有成本影响,您需要确保您获得正确的平衡。

而且不要忘记需要在OnStopOnDestroy
我很少使用意图释放资源,我觉得这种方式更好。

+0

这是OP在谈论使用“静态变量”时所指的。你不需要一个'Application'类,你可以使用静态变量。 OP正在寻找更“优雅”的解决方案;-) –

+0

谁是OP? :),使用Application类可以完成工作人员,并确保在应用程序开始前完成这些工作直到结束。为什么这个解决方案不够优雅?什么样的解决方案可以“优雅”?从Android的全局变量的综合支持? – CDrosos

+0

在正确的轨道错误只是一些背景信息,为什么这是一个有点不稳定......你的过程可以在任何时候被操作系统杀死(EG:活动已经背景一段时间,来自其他应用程序的高内存压力等) ,应用程序类可能会被拆除并重新创建,甚至不会注意。在这种情况下'Name'属性会被重置;改进的解决方案是通过getter和setter将其保存到共享首选项中,或通过数据库恢复“对象”。 – matthewrdev