英文:
SaveStateToBundle and ReloadFromBundle from MvxViewModel not called
问题
We have this Xamarin Forms Application. We are using MVVMCross for DependencyInjection , Navigation and more.
We now have the problem, that we can't work out, when the SaveStateToBundle and ReloadFromBundle are getting called. These methods should automatically be called, when the application goes into the tombstoning process on android, but that doesn't seem to happen.
We simulated the tombstoning by the android developer option "Don't keep activities" and also by writing a application, that fills a list with dummy data, until android has to clear up space and tombstones the application with mvvmcross
We are using on the Android Project MVVMCross 8.0.2 and MvvmCross.Forms 8.0.2
On the project with the viewmodels running on .NET Standard 2.1 and there we are using MVVMCross 8.0.2
We figured out, that it doesn't get called, by writing data in to the Xamarin Essentials Preferences by key and checking, if the key has the given value in it when restarting the application.
This is how we use it:
public class LoginViewModel : ViewModelBase, IFirstViewModel
{
(...)
protected override void SaveStateToBundle(IMvxBundle bundle)
{
Preferences.Set("testkey", "value");
base.SaveStateToBundle(bundle);
}
protected override void ReloadFromBundle(IMvxBundle state)
{
// Returns value of key or the default value "nothing"
Preferences.Get("testkey", "nothing");
base.ReloadFromBundle(state);
}
(...)
}
About the application setup:
- MainActivity extends MvxFormsAppCompatActivity<Setup, App, UI.App>:
[Activity(
Label = "Mobit.MES.Client",
Icon = "@mipmap/icon",
Theme = "@style/MainTheme",
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize,
LaunchMode = LaunchMode.SingleTask)]
public class MainActivity : MvxFormsAppCompatActivity<Setup, App, UI.App>
{
protected override void OnCreate(Bundle bundle)
{
(...)
base.OnCreate(bundle);
}
(...)
}
-
Setup from MvxFormsAndroidSetup<App, UI.App>:
-
App:
public class App : MvxApplication
{
public override void Initialize()
{
// Register all Services in this assembly.
CreatableTypes()
.EndingWith("Service")
.AsInterfaces()
.RegisterAsLazySingleton();
RegisterIoC();
RegisterCustomAppStart<AppStart>();
}
}
- UI.App:
public partial class App : Application
{
public App()
{
InitializeComponent();
}
}
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:controls="clr-namespace:Mobit.MES.Client.UI.Controls">
<Application.Resources>
(...)
</Application.Resources>
</Application>
英文:
We have this Xamarin Forms Application. We are using MVVMCross for DependencyInjection , Navigation and more.
We now have the problem, that we can't work out, when the SaveStateToBundle and ReloadFromBundle are getting called. These methods should automatically be called, when the application goes into the tombstoning process on android, but that doesn't seem to happen.
We simulated the tombstoning by the android developer option "Don't keep activities" and also by writing a applöication, that fills a list with dummy data, until android has to clear up space and tombstones the application with mvvmcross
We are using on the Android Project MVVMCross 8.0.2 and MvvmCross.Forms 8.0.2
On the project with the viewmodels running on .NET Standard 2.1 and there we are using MVVMCross 8.0.2
We figured out, that it doesn't get called, by writing data in to the Xamarin Essentials Preferences by key and checking, if the key has the given value in it when restarting the application.
This is how we use it:
public class LoginViewModel : ViewModelBase, IFirstViewModel
{
(...)
protected override void SaveStateToBundle(IMvxBundle bundle)
{
Preferences.Set("testkey", "value");
base.SaveStateToBundle(bundle);
}
protected override void ReloadFromBundle(IMvxBundle state)
{
// Returns value of key or the default value "nothing"
Preferences.Get("testkey", "nothing");
base.ReloadFromBundle(state);
}
(...)
}
About the application setup:
- MainActivity extends MvxFormsAppCompatActivity<Setup, App, UI.App>
[Activity(
Label = "Mobit.MES.Client",
Icon = "@mipmap/icon",
Theme = "@style/MainTheme",
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize,
LaunchMode = LaunchMode.SingleTask)]
public class MainActivity : MvxFormsAppCompatActivity<Setup, App, UI.App>
{
protected override void OnCreate(Bundle bundle)
{
(...)
base.OnCreate(bundle);
}
(...)
}
}
-
Setup from MvxFormsAndroidSetup<App, UI.App>
-
App:
public class App : MvxApplication
{
public override void Initialize()
{
// Register all Services in this assembly.
CreatableTypes()
.EndingWith("Service")
.AsInterfaces()
.RegisterAsLazySingleton();
RegisterIoC();
RegisterCustomAppStart<AppStart>();
}
}
- UI.App:
public partial class App : Application
{
public App()
{
InitializeComponent();
}
}
<?xml version="1.0" encoding="utf-8" ?> <Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:controls="clr-namespace:Mobit.MES.Client.UI.Controls"> <Application.Resources> (...) </Application.Resources> </Application>
答案1
得分: 1
在查看 8.0.2 分支时,似乎这个特定功能从未在 Xamarin.Forms 中实现。
要解决此问题,您需要连接到适当的页面生命周期事件并触发 ViewModel 方法。
英文:
Looking through the 8.0.2 branch. It seems like this specific feature was never implemented for Xamarin.Forms.
To work around this, you would have to hook into the appropriate Page lifecycle events and trigger the ViewModel methods.
答案2
得分: 0
I also had issues triggering tombstoning myself.
"Don't keep activities" didn't work for me as well.
To actually test tombstoning on Android you have to.
- use SaveStateToBundle and actually save something in the bundle (if the bundle is empty
ReloadFromBundle
won't be called) - start the app
- open the view which saves data to bundle
- push app to background
- call this command from CLI
adb shell am kill com.example.yourappid
- go to task list and bring back the app
Result: ReloadFromBundle
will be called
Mind that when you call adb shell am kill com.example.yourappid
you will be disconnected from the debugger, this is expected behavior.
If you want to debug this part, your best bet will be to use Log.Debug
inside ReloadFromBundle
and inspect logcat for the messages.
More details here:
https://github.com/MvvmCross/MvvmCross/pull/4552/files
英文:
I also had issues triggering tombstoning myself.
"Don't keep activities" didn't work for me as well.
To actually test tombstoning on Android you have to.
- use SaveStateToBundle and actually save something in the bundle (if the bundle is empty
ReloadFromBundle
won't be called) - start the app
- open the view which saves data to bundle
- push app to background
- call this command from CLI
adb shell am kill com.example.yourappid
- go to task list and bring back the app
Result: ReloadFromBundle
will be called
Mind that when you call adb shell am kill com.example.yourappid
you will be disconnected from the debugger, this is expected behavior.
If you want to debug this part, your best bet will be to use Log.Debug
inside ReloadFromBundle
and inspect logcat for the messages.
More details here:
https://github.com/MvvmCross/MvvmCross/pull/4552/files
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论