Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

You MUST call Xamarin.Forms.Init(); prior to using it

In my app.xaml.cs I create a new page.

 public App()
  {
      InitializeComponent();
      MainPage = new NavigationPage(new WrapLayoutPage());
  }

This page calls a static class, which uses the DependencyService to perform some tasks.

The line which throws the error:

var tmpTable = SqLiteHelper.GetItem<TableX>("someId");

SqLiteHelper:

public static class SqLiteHelper
{
    private static readonly SQLiteConnection DatabaseConnection = DependencyService.Get<ISqLite>().GetConnection();
    private static readonly object Locker = new object();

    public static DbObjectV3 GetItem<T>(Guid inId) where T : DbObjectV3, new()
    {
        lock (Locker)
        {
            var tmpItem = DatabaseConnection.Table<T>().FirstOrDefault(inItem => inItem.Id == inId);
            tmpItem.IsNewObject = false;
            return tmpItem;
        }
    }
}

This throws me a TypeInitializationException with the InnerException:

You MUST call Xamarin.Forms.Init(); prior to using it

It's somehow related to the static helper class, because prior to that call, I can use the DependencyService without any problems!

As mainlauncher I'm using a splash screen. In this class I do some startup work, which relies on the DependencyService.

SplashScreen:

 [Activity(Theme = "@style/MyTheme.Splash", NoHistory = true, MainLauncher = true)]
    public class SplashScreen : Activity
    {
        static readonly string TAG = "X:" + typeof(SplashScreen).Name;

        public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
        {
            base.OnCreate(savedInstanceState, persistentState);
            Log.Debug(TAG, "SplashActivity.OnCreate");
        }
}

My MainActivity:

 [Activity(Label = "FrameworkForms", Icon = "@drawable/icon", ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation, Theme = "@style/MainActivityTheme", MainLauncher = false)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            Xamarin.Forms.Forms.Init(this, bundle);
            App.ScreenWidth = (double)(Resources.DisplayMetrics.WidthPixels / Resources.DisplayMetrics.Density);
            LoadApplication(new App());
        }
    }

Now after changing the Activity in SplashScreen to FormsAppCompatActivity, I get another error.

Call Forms.Init() before Hide Keyboard

What's the thing here?

like image 295
greenhoorn Avatar asked Jan 04 '17 10:01

greenhoorn


1 Answers

This is pretty unfortunate. I used the wrong OnCreate() method in my SplashScreen.

I changed SplashScreen to:

 [Activity(Theme = "@style/MyTheme.Splash", NoHistory = true, MainLauncher = true)]
    public class SplashScreen : Activity
    {
        static readonly string TAG = "X:" + typeof(SplashScreen).Name;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            Xamarin.Forms.Forms.Init(this, savedInstanceState);
            Log.Debug(TAG, "SplashActivity.OnCreate");
        }


        protected override void OnResume()
        {
            base.OnResume();

            Task tmpStartupWork = new Task(() =>
            {
                Log.Debug(TAG, "Performing some startup work that takes a bit of time.");
                StartUpTasks.InitializeDatabaseCreation();
                Log.Debug(TAG, "Working in the background - important stuff.");
            });

            tmpStartupWork.ContinueWith(inT =>
            {
                Log.Debug(TAG, "Work is finished - start MainActivity.");
                StartActivity(new Intent(Application.Context, typeof(MainActivity)));
            }, TaskScheduler.FromCurrentSynchronizationContext());

            tmpStartupWork.Start();
        }
    }

Unfortunately, the documentation on Xamarin about creating a splash screen uses the OnCreate() method with 2 parameters!

like image 95
greenhoorn Avatar answered Oct 12 '22 01:10

greenhoorn