1

有時,當我的Xamarin.Android應用程序被殺並且應用程序需要重新創建其主要活動時,某些佈局不可用,並且屏幕不顯示任何視圖。無效的佈局資源

通過按設備返回按鈕,然後重新打開應用程序,其主要活動得到正確實例化和顯示。

這是負責加載用於佈局代碼:

// Returns null whenever trying to recreate views right after the application got killed by Android (Due to some multi-tasking reasons). Otherwise, it returns valid instances. 
var layout = DroidResources.LoadLayout (context, parent, layoutName); 

見下截圖(文中略):

前/後系統將自動重新創建活動。

Before After

我使用:

  • Xamarin.Android 4.10
  • MvvmCross 3.0.13 - Android.Dialog

可能有些你點我一個方向關於如何解決這個問題? 我對這兩種描述的技術都很陌生。任何幫助將不勝感激。從DDMS應用程序檢索


日誌:

E/Android.Dialog(9171): LoadLayout failed: You must call DroidResources.Initialize(Resource.Layout) before using Dialogs 
E/Android.Dialog(9171): LoadLayout failed: You must call DroidResources.Initialize(Resource.Layout) before using Dialogs 
E/Android.Dialog(9171): LoadLayout failed: You must call DroidResources.Initialize(Resource.Layout) before using Dialogs 
E/Android.Dialog(9171): LoadLayout failed: You must call DroidResources.Initialize(Resource.Layout) before using Dialogs 
E/Android.Dialog(9171): LoadLayout failed: You must call DroidResources.Initialize(Resource.Layout) before using Dialogs 
E/Android.Dialog(9171): LoadLayout failed: You must call DroidResources.Initialize(Resource.Layout) before using Dialogs 
E/Android.Dialog(9171): ViewElement: Failed to load resource: MenuSeparator 
E/Android.Dialog(9171): LoadLayout failed: You must call DroidResources.Initialize(Resource.Layout) before using Dialogs 
E/Android.Dialog(9171): LoadLayout failed: You must call DroidResources.Initialize(Resource.Layout) before using Dialogs 
E/Android.Dialog(9171): LoadLayout failed: You must call DroidResources.Initialize(Resource.Layout) before using Dialogs 
E/Android.Dialog(9171): ViewElement: Failed to load resource: MenuSeparator 

我想明白爲什麼當正常打開應用程序的DroidResources類被初始化,但它沒有被初始化當應用程序只是從背景返回。我猜在後臺時間Android強制它的實例被垃圾收集,但不是整個應用程序。

我也覺得我可能是錯初始化它,那是我Setup.cs文件:

/// <summary> 
/// MvvmCross setup class. 
/// Allows Android.Dialog usage during application lifecycle 
/// </summary> 
public class Setup : MvxAndroidDialogSetup 
{ 
    public Setup (Context applicationContext) 
     : base (applicationContext) 
    { 
    } 

    protected override IMvxApplication CreateApp() 
    { 
     return new MvvmCrossApplication(); 
    } 
} 


// MvvmCross internal application. 
public class MvvmCrossApplication : MvxApplication 
{ 
    public override void Initialize() 
    { 
     // Setup initial application view which will be loaded as soon as the MvvmCross framework 
     // initialization has been completed. 
     RegisterAppStart<ApplicationViewModel>(); 
    } 
} 

// 
// These next classes ApplicationViewModel and ApplicationView are auxiliary classes 
// needed by the MvvmCross framework to ensure that others application classes are loaded 
// only after the MvvmCross initilization has been completed. 
public class ApplicationViewModel : MvxViewModel 
{ 
} 

[Activity (Theme = "@style/Theme.Transparent", NoHistory = true)] 
public class ApplicationView : MvxActivity 
{ 
    protected override void OnResume() 
    { 
     base.OnResume(); 

     // Start the application main activity. 
     StartActivity (typeof(ApplicationMainActivity)); 
    } 
} 

直到現在我只是用從MvvmCross庫Android.Dialog的DLL。但是我會盡快使用ViewModel來啓動。

這裏遵循ApplicationMainActivity源代碼:

/// <summary> 
/// Application activity. 
/// </summary> 
/// <remarks>A transparent activity used to recreate current application screens workflow.</remarks> 
[Activity (Theme = "@style/Theme.Transparent", NoHistory = true)] 
public class ApplicationMainActivity : ClientUserActivity 
{ 
    #region Lifecycle methods 

    protected override void OnCreate (Bundle bundle) 
    { 
     base.OnCreate (bundle); 

     if (ClientUser.IsLoggedIn()) { 

      if (ClientUser.ShouldShowWizard()) { 

        // Show the wizard screen 
        StartActivity (wizardActivity); 

       } else { 

        // Show the main menu screen 
        StartActivity (typeof(NavigationDrawerActivity)); 
       } 

     } else { 
      // Show the welcome screen 
      StartActivity (typeof(WelcomeActivity)); 
     } 
    } 
    ... 
+0

什麼'var layout = DroidResources.LoadLayout(context,parent,layoutName);'確實做? – Cheesebaron

+0

嗨@Cheesebaron,這裏遵循DroidResources類的源代碼:https://github.com/MvvmCross/MvvmCross/blob/162a816d148df224df0b8f635aeafe30c0910de9/CrossUI/CrossUI.Droid/DroidResources.cs它應該使用分配的layoutName加載Android佈局。 – georgepiva

+0

什麼是「ApplicationMainActivity」,爲什麼每次ApplicationView活動恢復時都要啓動它? – Stuart

回答

3

正如你在這個問題張貼層在層的代碼,我得到越來越多的困惑,你是否實際使用MvvmCross。

如果您只是使用MvvmCross Android。對話口 - 而不是使用MvvmCross - 那麼你需要找到一種方式,做了錯誤信息,要求你做:

You must call DroidResources.Initialize(Resource.Layout) before using Dialogs 

在一個「正常」 MvvmCross應用程序,就可以避免這個問題,因爲任何MvxActivity將確保SetupOnCreate之前創建和初始化完成了 - Setup包括:

protected virtual void InitializeDialogBinding() 
    { 
     var finder = Mvx.Resolve<IMvxAppResourceTypeFinder>(); 
     var resourceType = finder.Find(); 
     var nestedResourceType = resourceType.GetNestedTypes().FirstOrDefault(x => x.Name == "Layout"); 
     DroidResources.Initialize(nestedResourceType); 
    } 

看到https://github.com/MvvmCross/MvvmCross/blob/v3/Cirrious/Cirrious.MvvmCross.Dialog.Droid/MvxAndroidDialogSetup.cs#L40

如果你想實現non-MvxActivity活動,那麼你需要找到一些其他方式來確保啓動設置和/或加載droid資源。