Reputation: 1561
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?
Upvotes: 13
Views: 21261
Reputation: 1113
I also came across this mistake. The cause of the error was that I wanted to change my namespace. From
public partial class AppDelegate :
global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
I changed it to:
using Xamarin.Forms.Platform.iOS;
public partial class AppDelegate : FormsApplicationDelegate
Then I saw the following:
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
I thought, it would be useful to adjust that as well... without thinking more exactly about it. And I wrote:
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
this.Init();
A while later, I got the mistake and had to laboriously search for the cause. Finally I found and fixed it. Maybe it can help someone :-) Cheers...
Upvotes: 0
Reputation: 1561
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!
Upvotes: 12