xamarin.android – 升级到6.0版后,MvvmCross App无法启动

前端之家收集整理的这篇文章主要介绍了xamarin.android – 升级到6.0版后,MvvmCross App无法启动前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我将我的应用程序升级到MvvmCross 6.0版.现在它可以进入启动画面并且不做任何其他事情.通过查看控制台,我可以看到服务正在启动.这是我的app.cs:
  1. public class App : MvxApplication
  2. {
  3. public override void Initialize()
  4. {
  5. MPS.ApplicationName = Settings.ApplicationName;
  6. EventLog.ApplicationName = Settings.ApplicationName;
  7. BlobCache.ApplicationName = Settings.ApplicationName;
  8.  
  9. CreatableTypes()
  10. .EndingWith("Service")
  11. .AsInterfaces()
  12. .RegisterAsLazySingleton();
  13.  
  14. CreatableTypes()
  15. .EndingWith("Singleton")
  16. .AsInterfaces()
  17. .RegisterAsSingleton();
  18.  
  19. //RegisterAppStart(new CustomAppStart());
  20. //RegisterNavigationServiceAppStart<Loginviewmodel>();
  21. RegisterAppStart<Loginviewmodel>();
  22. }
  23.  
  24. }

这是非常基本的.我已经转换为新的导航系统因此RegisterNavigationServiceAppStart.那将不再解决,所以我回到了直接的RegisterAppStart.启动画面出现然后停止.如果重要,splashscreen.cs如下:

  1. [Activity(
  2. Label = "@string/ApplicationName",MainLauncher = true,Icon = "@drawable/icon",Theme = "@style/Theme.Splash",NoHistory = true)]
  3. //,ScreenOrientation = ScreenOrientation.Landscape)]
  4. public class SplashScreen : MvxSplashScreenActivity
  5. {
  6. public SplashScreen()
  7. : base(Resource.Layout.SplashScreen)
  8. {
  9. }
  10. }

这很香草,但我知道事情已经发生了变化.我的setup.cs如下:

  1. public class Setup : MvxAndroidSetup
  2. {
  3. //public Setup(Context applicationContext)
  4. // : base(applicationContext)
  5. //{
  6. //}
  7.  
  8. protected override IMvxApplication CreateApp()
  9. {
  10. return new App();
  11. }
  12.  
  13. //protected override IMvxTrace CreateDebugTrace()
  14. //{
  15. // return new DebugTrace();
  16. //}
  17.  
  18. protected override IMvxAndroidViewPresenter CreateViewPresenter()
  19. {
  20. return new MvxAppCompatViewPresenter(AndroidViewAssemblies);
  21. }
  22.  
  23. protected override void FillValueConverters(IMvxValueConverterRegistry registry)
  24. {
  25. base.FillValueConverters(registry);
  26. registry.AddOrOverwrite("DateToStringConverter",new DateToStringConverter());
  27. registry.AddOrOverwrite("FloatToStringConverter",new FloatToStringConverter());
  28. registry.AddOrOverwrite("DecimalToStringConverter",new DecimalToStringConverter());
  29. registry.AddOrOverwrite("BoolToViewStatesConverter",new BoolToViewStatesValueConverter());
  30. registry.AddOrOverwrite("ShipmentToOriginConverter",new ShipmentToOriginConverter());
  31. registry.AddOrOverwrite("ShipmentToDestinationConverter",new ShipmentToDestinationConverter());
  32. //registry.AddOrOverwrite("CustomName2",new AnotherVerySpecialValueConverter("Summer"));
  33. }
  34.  
  35. protected override void FillTargetFactories(MvvmCross.Binding.Bindings.Target.Construction.IMvxTargetBindingFactoryRegistry registry)
  36. {
  37. base.FillTargetFactories(registry);
  38. registry.RegisterCustomBindingFactory<EditText>("FocusText",textView => new MvxEditTextFocusBinding(textView));
  39. registry.RegisterCustomBindingFactory<TextView>("FocusChange",textView => new MvxTextViewFocusChangeBinding(textView));
  40. //registry.RegisterCustomBindingFactory<MvxSpinner>("ItemSelected",// spinner => new MvxSpinnerItemSelectedBinding(spinner));
  41. }
  42.  
  43. protected override IEnumerable<Assembly> AndroidViewAssemblies => new List<Assembly>(base.AndroidViewAssemblies)
  44. {
  45. typeof(MvvmCross.Droid.Support.V7.RecyclerView.MvxRecyclerView).Assembly
  46. };
  47.  
  48. }

我对它做的唯一改变是删除构造函数.根据6.0版的文档,构造函数不再有参数,所以我没有理由调用它.有人可以帮忙吗?

**更新**

添加了一个MainApplication.cs,如下所示:

  1. [Application]
  2. public class MainApplication : MvxAppCompatApplication<Setup,App>
  3. {
  4. public MainApplication(IntPtr javaReference,JniHandleOwnership transfer) : base(javaReference,transfer)
  5. {
  6. }
  7. }

这让我超越了启动画面,但挂起了Loginviewmodel的Initialize.

*日志*

也许这会有所帮助.以下是事件日志条目:

  1. 2018-04-17 12:17:06 [TRACE] (MvvmCross.Core.MvxSetup) Setup: Primary start
  2. 2018-04-17 12:17:06 [TRACE] (MvvmCross.Core.MvxSetup) Setup: FirstChance start
  3. 2018-04-17 12:17:06 [TRACE] (MvvmCross.Core.MvxSetup) Setup: PlatformServices start
  4. 2018-04-17 12:17:06 [TRACE] (MvvmCross.Core.MvxSetup) Setup: MvvmCross settings start
  5. 2018-04-17 12:17:06 [TRACE] (MvvmCross.Core.MvxSetup) Setup: Singleton Cache start
  6. 2018-04-17 12:17:06 [TRACE] (MvvmCross.Core.MvxSetup) Setup: ViewDispatcher start
  7. 2018-04-17 12:17:06 [TRACE] (MvvmCross.Core.MvxSetup) Setup: Bootstrap actions
  8. 2018-04-17 12:17:07 [TRACE] (MvvmCross.Logging.MvxLog) No view model type finder available - assuming we are looking for a splash screen - returning null
  9. 2018-04-17 12:17:07 [TRACE] (MvvmCross.Core.MvxSetup) Setup: StringToTypeParser start
  10. 2018-04-17 12:17:07 [TRACE] (MvvmCross.Core.MvxSetup) Setup: CommandHelper start
  11. 2018-04-17 12:17:07 [TRACE] (MvvmCross.Core.MvxSetup) Setup: PluginManagerFramework start
  12. 2018-04-17 12:17:07 [TRACE] (MvvmCross.Core.MvxSetup) Setup: Create App
  13. 2018-04-17 12:17:07 [TRACE] (MvvmCross.Core.MvxSetup) Setup: NavigationService
  14. 2018-04-17 12:17:07 [TRACE] (MvvmCross.Core.MvxSetup) Setup: Load navigation routes
  15. 2018-04-17 12:17:07 [TRACE] (MvvmCross.Core.MvxSetup) Setup: App start
  16. 2018-04-17 12:17:07 [TRACE] (MvvmCross.Core.MvxSetup) Setup: Application Initialize - On background thread
  17. 2018-04-17 12:17:08 [TRACE] (MvvmCross.Core.MvxSetup) Setup: viewmodelTypeFinder start
  18. 2018-04-17 12:17:08 [TRACE] (MvvmCross.Core.MvxSetup) Setup: ViewsContainer start
  19. 2018-04-17 12:17:08 [TRACE] (MvvmCross.Core.MvxSetup) Setup: Views start
  20. 2018-04-17 12:17:08 [TRACE] (MvvmCross.Core.MvxSetup) Setup: CommandCollectionBuilder start
  21. 2018-04-17 12:17:08 [TRACE] (MvvmCross.Core.MvxSetup) Setup: NavigationSerializer start
  22. 2018-04-17 12:17:08 [TRACE] (MvvmCross.Core.MvxSetup) Setup: InpcInterception start
  23. 2018-04-17 12:17:08 [TRACE] (MvvmCross.Core.MvxSetup) Setup: InpcInterception start
  24. 2018-04-17 12:17:08 [TRACE] (MvvmCross.Core.MvxSetup) Setup: LastChance start
  25. 2018-04-17 12:17:08 [TRACE] (MvvmCross.Core.MvxSetup) Setup: Secondary end
  26. 2018-04-17 12:17:08 [TRACE] (MvvmCross.Logging.MvxLog) AppStart: Application Startup - On UI thread

我进一步追踪它.它挂在视图模型中的Initialize()上.我创建了一个测试来演示:

  1. public class Firstviewmodel : Mvxviewmodel
  2. {
  3.  
  4. public Firstviewmodel()
  5. {
  6. Task.Run(async () =>
  7. {
  8. var l = await ListDataSource.GetLocations();
  9. var m = l;
  10. });
  11. }
  12.  
  13. public async override Task Initialize()
  14. {
  15. await base.Initialize();
  16. var l = await ListDataSource.GetLocations();
  17. var m = l;
  18. }
  19.  
  20. }

如果我在两个var m = l上设置一个断点,它将到达构造函数中的断点,但永远不会到达Initialize中的断点. GetLocations是:

  1. public async static Task<LocationList> GetLocations()
  2. {
  3. ListServiceClient client = NewClient();
  4.  
  5. LocationList ret = null;
  6. bool TryCache = false;
  7.  
  8. try
  9. {
  10. //ret = await client.GetLocationListAsync();
  11. ret = await Task<LocationList>.Factory.FromAsync((asyncCallback,asyncState) => client.BeginGetLocationList(asyncCallback,asyncState),(asyncResult) => client.EndGetLocationList(asyncResult),null);
  12.  
  13. client.Close();
  14. await BlobCache.LocalMachine.InsertObject("Locations",ret,DateTimeOffset.Now.AddDays(Settings.CacheDays));
  15. }
  16. catch (TimeoutException ex)
  17. {
  18. client.Abort();
  19. EventLog.Error(ex.ToString());
  20. TryCache = true;
  21. }
  22. catch (CommunicationException ex)
  23. {
  24. client.Abort();
  25. EventLog.Error(ex.ToString());
  26. TryCache = true;
  27. }
  28. catch (Exception ex)
  29. {
  30. EventLog.Error(ex.ToString());
  31. TryCache = true;
  32. }
  33.  
  34. if (TryCache)
  35. {
  36. try
  37. {
  38. ret = await BlobCache.LocalMachine.GetObject<LocationList>("Locations");
  39. }
  40. catch (KeyNotFoundException)
  41. {
  42. ret = null;
  43. }
  44. }
  45.  
  46. return ret;
  47. }

如果在Client.Close()上设置一个断点,如果从构造函数调用它,它将到达那里,但如果从Initialize调用则不会.

解决方法

我的问题是双重的.首先,当您使用Android升级到6.0版时,您现在必须包含MainApplication.cs,如下所示:
  1. [Application]
  2. public class MainApplication : MvxAppCompatApplication<Setup,transfer)
  3. {
  4. }
  5. }

如果没有这个,你将被困在SplashScreen上.其次,您需要知道您显示的第一个viewmodel中的Initialize必须是同步的.正如@Ale_lipa所提到的,一位MvvmCross作者撰写了一篇博客文章,解释了为什么会这样做以及如何处理它.

https://nicksnettravels.builttoroam.com/post/2018/04/19/MvvmCross-Initialize-method-on-the-first-view-model.aspx

简而言之,如果您使用的是SplashScreen,并且您确实需要将第一个viewmodel的Initialize作为Async,则可以按如下方式添加CustomAppStart:

  1. public class CustomMvxAppStart<Tviewmodel> : MvxAppStart<Tviewmodel>
  2. where Tviewmodel : IMvxviewmodel
  3. {
  4. public CustomMvxAppStart(IMvxApplication application,IMvxNavigationService navigationService) : base(application,navigationService)
  5. {
  6. }
  7.  
  8. protected override void NavigateToFirstviewmodel(object hint)
  9. {
  10. NavigationService.Navigate<Tviewmodel>();
  11. }
  12. }

在你的App.cs中,替换你的:

  1. RegisterAppStart<Firstviewmodel>();

有:

  1. RegisterCustomAppStart<CustomMvxAppStart<Firstviewmodel>>();

这将允许您的第一个Initialize异步.我只确定它适用于Android,并且只有在使用SplashScreen时才有效.

猜你在找的Android相关文章