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);

见下一个截图(文本被省略):

系统自动重新创建活动之前/之后。

前 后

我在用:

  • 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));
        }
    }
    ...
4

1 回答 1

3

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

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

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

在“正常”的 MvvmCross 应用程序中,可以避免此问题,因为任何MvxActivity将确保在完成Setup之前创建和初始化OnCreate-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 资源。

于 2013-10-30T18:12:42.737 回答