无效的布局资源

时间:2013-10-30 16:33:43

标签: android-layout xamarin.android mvvmcross android-resources

有时当我的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。但我会尽快使用ViewModels开始。

以下是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));
        }
    }
    ...

1 个答案:

答案 0 :(得分:3)

当你在这个问题中发布层层代码时,我对你是否真正使用MvvmCross越来越感到困惑。

如果您只是使用MvvmCross Android.Dialog端口 - 而不是使用MvvmCross - 那么您需要找到一种方法来处理错误消息要求您执行的操作:

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

在“普通”MvvmCross应用程序中,可以避免此问题,因为任何MvxActivity都会确保在Setup完成之前创建并初始化OnCreateSetup包括:

    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活动,那么您需要找到一些其他方法来确保启动设置和/或加载机器人资源。