2015-10-19 63 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