2013-05-17 41 views
1

我一直在使用Xamarin的Mono for Android和MonoCross框架來開發當前在Android(2.3,4.0及其他)下運行的應用程序。 在我的應用程序中,我有一個主要活動,用戶可以從哪裏開始新活動,然後再開始其他活動等等。 (例如Main - > A - > B - > C)MonoCross:重新啓動應用程序時MXDialogActivityView.OnCreate()中的KeyNotFoundException

有時候,我得到以下問題: 當應用程序暫停(或停止)一段時間(即不在前臺)和/或其他消耗內存的應用程序都已啓動,然後我返回到我的應用程序,但未正確重新啓動。 這意味着,我可以看到部分活動C(窗口標題)幾秒鐘,然後C消失,B來了等等與A和主。 Main消失後,我回到了主屏幕。當我再次啓動我的應用程序時,它將啓動Main活動。

在logcat中,我看到這些條目(我希望我沒有削減太多):

05-15 14:36:39.732 I/ActivityManager( 598): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=de.branchare.adwais2013/branchware.adwais.droid.MainActivity u=0} from pid 1349 
... 
05-15 14:36:39.792 I/ActivityManager( 598): Start proc de.branchare.adwais2013 for activity de.branchare.adwais2013/branchware.adwais.droid.views.ActivityC: pid=29032 uid=10025 gids={3003, 1015, 1028} 
... 
05-15 14:36:39.952 I/ActivityThread(29032): Pub de.branchare.adwais2013.mono.MonoRuntimeProvider.__mono_init__: mono.MonoRuntimeProvider 
... 
05-15 14:36:42.966 I/MonoDroid(29032): at MonoCross.Droid.MXDialogActivityView`1<Branchware.Adwais.ModelContainer`1<Branchware.Adwais.Model.Visit>>.OnCreate (Android.OS.Bundle) <0x00053> 
05-15 14:36:42.966 I/MonoDroid(29032): at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (intptr,intptr,intptr) <0x00057> 
05-15 14:36:42.966 I/MonoDroid(29032): at (wrapper dynamic-method) object.15bfff07-188b-4aff-a34f-ab878a2a545f (intptr,intptr,intptr) <0x00043> 
05-15 14:36:43.036 E/mono (29032): 
05-15 14:36:43.036 E/mono (29032): Unhandled Exception: 
05-15 14:36:43.036 E/mono (29032): System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary. 
05-15 14:36:43.036 E/mono (29032): at System.Collections.Generic.Dictionary`2[System.Type,System.Object].get_Item (System.Type key) [0x00000] in <filename unknown>:0 
05-15 14:36:43.036 E/mono (29032): at MonoCross.Droid.MXDialogActivityView`1[Branchware.Adwais.ModelContainer`1[Branchware.Adwais.Model.Visit]].OnCreate (Android.OS.Bundle bundle) [0x00000] in <filename unknown>:0 
05-15 14:36:43.036 E/mono (29032): at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (IntPtr jnienv, IntPtr native__this, IntPtr native_savedInstanceState) [0x00000] in <filename unknown>:0 
05-15 14:36:43.036 E/mono (29032): at (wrapper dynamic-method) object:15bfff07-188b-4aff-a34f-ab878a2a545f (intptr,intptr,intptr) 
05-15 14:36:43.036 I/mono (29032): [ERROR] FATAL UNHANDLED EXCEPTION: System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary. 
05-15 14:36:43.036 I/mono (29032): at System.Collections.Generic.Dictionary`2[System.Type,System.Object].get_Item (System.Type key) [0x00000] in <filename unknown>:0 
05-15 14:36:43.036 I/mono (29032): at MonoCross.Droid.MXDialogActivityView`1[Branchware.Adwais.ModelContainer`1[Branchware.Adwais.Model.Visit]].OnCreate (Android.OS.Bundle bundle) [0x00000] in <filename unknown>:0 
05-15 14:36:43.036 I/mono (29032): at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (IntPtr jnienv, IntPtr native__this, IntPtr native_savedInstanceState) [0x00000] in <filename unknown>:0 
05-15 14:36:43.036 I/mono (29032): at (wrapper dynamic-method) object:15bfff07-188b-4aff-a34f-ab878a2a545f (intptr,intptr,intptr) 
05-15 14:36:43.136 I/ActivityManager( 598): Recipient 29032 
05-15 14:36:43.136 I/ActivityManager( 598): Process de.branchare.adwais2013 (pid 29032) has died. 
05-15 14:36:43.136 D/InputManager( 598): setFocusedApplication Exception: java.lang.NullPointerException 
... 
05-15 14:36:43.136 W/ActivityManager( 598): Force removing ActivityRecord{41cc9df0 de.branchare.adwais2013/branchware.adwais.droid.views.ActivityC}: app died, no saved state 
... 
05-15 14:36:43.166 I/ActivityManager( 598): Start proc de.branchare.adwais2013 for activity de.branchare.adwais2013/branchware.adwais.droid.views.ActivityB: pid=29052 uid=10025 gids={3003, 1015, 1028} 

在我看來,彷彿
- Android已經銷燬()代管我的活動,而他們暫停(我知道這是正確的行爲)
- Android然後嘗試創建()當用戶返回到我的應用程序的活動的新實例(這也是正確的)
- 在框架的MXDialogActivityView.OnCreate(),在調用Render()之前,MonoCross嘗試從MXDroidContainer獲取模型:

// fetch the model before rendering!!! 
Model = (T)MXDroidContainer.ViewModels[typeof(T)]; 
// render the model within the view 
Render(); 

- 這是拋出KeyNotFoundException(方法Render()永遠不會被調用)的地方,因爲MXDroidContainer不再包含ViewModel。 (可能這個實例也是在此期間重新創建的,因此不包含任何數據。)

我知道Android可以(甚至必須)銷燬暫停/停止的應用程序。 但是看到我的應用程序重新啓動整個活動堆棧然後完全消失,並且不得不重新啓動它,這非常煩人。

我想實現的是:
a)我的應用程序應該重新啓動停止位置(在活動C中)。
如果這是不可能的,那麼
B)我的應用程序應該重新啓動在MainLauncher(在活動主),完全重新初始化。

我已經閱讀過很多關於活動生命週期,啓動模式,AlwaysRetainTaskState,... 但我還沒有找到解決我的問題的方法。

任何幫助或指針將不勝感激。

TIA, Manfred。

回答

1

我認爲你對Activity生命週期的分析以及它與MonoCross框架的交互是正確的。

我不知道如果MonoCross擁有目前對於這種「立碑」的任何處理 - 所以,如果你想解決這個問題,那麼你就需要做這樣做你自己。

要做到這一點,你需要:

  • 使用protected override void OnSaveInstanceState(Bundle outState)方法保存/連載您查看任何當前的模型數據到捆綁
  • 改寫默認MX*ActivityView.OnCreate行爲,以使用將包含已保存實例狀態的bundle參數。

我在MvvmCross中最近做了同樣類型的事情。然而,模型的生命週期在MvvmCross中有很大的不同 - 我相信MonoCross始終只在內存中保留每個模型的一個實例,而MvvmCross只是將每個View鏈接到它的ViewModel - 所以ViewModel生命週期與View生命週期完全相關。因此,我擔心Mvx代碼可能無法輕鬆回到MX ...

+0

嗨,斯圖亞特,非常感謝您的快速回答。我正在度假,所以我剛纔讀了。我會嘗試捆綁的東西。我有一些包含數百個條目的模型的ListViews,它們似乎不易(並且很快)保存在OnSaveInstanceState()中。但我想我可以保存參數字典,然後重新導航到視圖。再次感謝這一點。順便說一句:有沒有人使用MonoCross框架?我覺得那裏沒有太多活動。再見,曼弗雷德。 – user2393042

+0

對於順便說一句,我認爲你最好的選擇是在他們的Google Group上詢問。我在Evolve與來自ITR的兩位傢伙交談,他們談論了很多客戶和用戶,並提到他們即將推出新版本。 – Stuart