2013-05-17 1 views
1

Я использовал Xamarin's Mono для Android и среду MonoCross для разработки приложения, которое в настоящее время работает под управлением Android (2.3, 4.0 и других). В моем приложении у меня есть основное действие, с которого пользователь может начинать новые действия, которые снова запускают другие действия и так далее. (например, Main -> A -> B -> C)MonoCross: KeyNotFoundException в MXDialogActivityView.OnCreate() при повторном запуске приложения

Время от времени у меня возникает следующая проблема: Когда приложение приостановлено (или остановлено) в течение некоторого времени (то есть не на переднем плане) и/или другие приложения, занимающиеся потреблением памяти, и затем я возвращаюсь в свое приложение, оно не перезапускается правильно. Это означает, что я могу видеть части активности 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 имеет Destroy() эд свою деятельность в то время как они были приостановлено (что я знаю правильно)
- Android затем пытается создать() новые экземпляры действий, когда пользователь вернется в мое приложение (это тоже верно)
- В MXDialogActivityView.OnCreate() MonoCross пытается извлечь модель из MXDroidContainer перед вызовом Render():

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

- Здесь генерируется исключение KeyNotFoundException (метод Render() никогда не вызывается), поскольку MXDroidContainer больше не содержит ViewModels. (Вероятно, этот экземпляр также был заново создан и, следовательно, не содержит никаких данных.)

Я знаю, что Android может (или даже должен) уничтожать приостановленные/остановленные приложения. Но очень досадно наблюдать за тем, как мое приложение возвращает весь стек активности, а затем полностью исчезает, и ему необходимо повторно запустить его.

Чего бы я хотел достичь:
a) Мое приложение должно перезапустить, где оно остановлено (в действии C).
Если это невозможно, то
b) Мое приложение должно перезагрузиться в MainLauncher (в основной деятельности), полностью переинициализироваться.

Я уже много читал (и много играл) о жизненном цикле деятельности, режимах запуска, AlwaysRetainTaskState, ... Но я еще не нашел решение моей проблемы.

Любые помощь или указатели будут очень признательны.

TIA, Manfred.

ответ

1

Я думаю, что ваш анализ жизненного цикла деятельности и ее взаимодействие с каркасом MonoCross верны.

Я не уверен, что у MonoCross есть какая-либо обработка в настоящее время для такого рода «надгробных камней», поэтому, если вы хотите справиться с этим, тогда вам нужно будет сделать это сами.

Чтобы сделать это, вам нужно:

  • использовать метод protected override void OnSaveInstanceState(Bundle outState) для сохранения/сериализации текущих данных Модели для вашего View в Bundle
  • переопределить поведение по умолчанию MX*ActivityView.OnCreate для того, чтобы использовать параметр bundle, который будет содержать сохраненное состояние экземпляра.

В последнее время я делал то же самое в MvvmCross. Тем не менее, жизненный цикл моделей очень отличается в MvvmCross - я считаю, что MonoCross всегда хранит ровно один экземпляр каждой модели в памяти, тогда как MvvmCross просто связывает каждый вид с ViewModel, поэтому lifecyle ViewModel привязан именно к виду lifecyle. Из-за этого я боюсь, что код Mvx не может легко переноситься обратно в MX ...

+0

Привет, Стюарт, большое спасибо за ваш быстрый ответ. Я был в отпуске, поэтому я прочитал его сейчас. Я попробую штуку. У меня есть ListViews, содержащий модели с сотнями записей, которые не кажутся легко (и быстро) сохраненными в OnSaveInstanceState(). Но я думаю, что я могу сохранить словарь параметров, а затем снова перейти к представлению. Еще раз спасибо за этот вопрос. BTW: Есть ли кто-нибудь там, используя рамки MonoCross? У меня сложилось впечатление, что там не так много. Пока, Манфред. – user2393042

+0

Для BTW, я думаю, ваш лучший выбор - спросить в своей группе Google. Я разговаривал с двумя парнями из ITR в Evolve, и они говорили о множестве клиентов и пользователей - и упомянули, что они были выпущены в ближайшее время. – Stuart

 Смежные вопросы

  • Нет связанных вопросов^_^