Reusing Xamarin.Forms.Application while LoadApplication in Xamarin Android - xamarin

How bad idea is to create application only once and use it all time when calling OnCreate in Android app:
protected override void OnCreate(Bundle bundle)
{
...
if(FirstRun)
_app = new App(new AndroidInitializer());
LoadApplication(_app);
}
The application resumes much faster. I did not noticed any issues during basic tests. FirstRun and _app are static properties.
OnCreate is called again for new activity when previous activity was destroyed. It happens for example when exiting app with back button or changing theme to dark.

First of all, a Xamarin Forms Application doesn't have an OnCreate method. An Android Activity has.
The activity's OnCreate is only called when FirstRun is true - when the activity's reused, the system calls OnRestart and OnStart, as described in the docs. If the activity get's destroyed, the FirstRun flag won't survive.

Related

Load startup model in platform project code and pass it to PCL on Xamarin Forms Initialization

The application I'm currently working on requires data to be retrieved from a web service during app startup that roughly takes 1.5 seconds. After the data is retrieved, it needs to be displayed on the MainPage and that is another 1.5 - 2 seconds since the data is mostly URLs of images that have to be displayed, in my case, using ffimageloading library; which means actually downloading those images first to be displayed.
I have splash startup screens for both Android and iOS implemented separately in platform projects but splash screen only stays up for the amount of time Xamarin Forms needs to load and afterwards disappears not waiting for my actual model to load from the web service. I have searched for solutions to extend the splash screen duration and mostly every solution I have read involves creating another splash screen page, loading page if you will, that is already controlled in PCL project but having two separate splash loading screens just seams not feasible to me at the moment.
So I was wondering, how would one load the initial model in platform projects, during the actual splash screen, and then later pass it to PCL project when Xamarin Forms has finished initialization, presumably to App.xaml.cs 's App() constructor function?
There is no code or enough details so I am assuming this is what you want to do.
Call the APIs asynchrnously , till then show splash screen.
Before assigning MainPage in your App.xaml.cs you should call these APIs asynchronously with await and then you use the same for binding of your mainpage
public App()
{
InitializeComponent();
//do all my prefetch stuff for app initialization.
// API and what not
var viewmodel = new AppMainViewModel();
await viewmodel.CallFooFetchAsync();
await viewmodel.BlahBlahAsync();
MainPage = new NavigationPage(new AppMainPage(viewmodel));
}
In Page
public AppMainPage(AppMainViewModel vm)
{
BindingContext =vm;
}
So by the time page loads it has all the data handy.
You can explore adding this code in OnAppearing of the page.
Note that the concept of default Splash screen is just to show an image(with different theme in Android) and setting image in iOS. You need to have conventional UI technically its not splash screen anymore.
Alternatively you can get shared project handle in native
Android Sp
protected override void OnCreate(Bundle bundle)
{
...
var app = new App(); //this will be shared project App object
Device.BeginInvokeOnMainThread(async () => await app.DoPrefetchStuffFirst()); //API calls if needed in this async method
//then
LoadApplicationm(app)
}
You can do similar thing in iOS AppDelegate
And if you call native specific methods in platforms (may be for API calls) then you would use DependencyService feature , that will pass it to shared project or Custom renderer based on where you want to use it.

Is there any final even happen before a XF application exits for ever?

I realize there are these events:
protected override void OnSleep()
{
base.OnSleep();
}
protected override void OnResume()
{
base.OnResume();
}
But is there any event that is called in which I could perform a logging action, before the app is finally swiped out of view and closed?
No there are only 3 lifecycle events for a Xamarin.Forms application. See documentation. They are:
OnStart(), OnSleep(), and OnResume().
What you could do is just do whatever you need to in OnSleep and reverse it in OnResume. That way whether the user comes back or not, you've handled what you need to handle.
No, and it is technically impossible to make something like that on iOS and Android. On UWP you could make some native code that would invoke this on Xamarin.Forms project. But I don't think that anyone is interested in such UWP only feature on Xamarin.Forms, so if you need it you will probably need to implement it yourself.

When using Appcenter, can I still call VersionTracking inside the App constructor?

The application I am working with uses AppCenter with code like this:
public App()
{
InitializeComponent();
VersionTracking.Track();
VersionChecks();
VersionChecks();
DB.CreateTables();
DB.GetSettings();
DB.PopulateTables();
SetDeviceInfo();
SetResourceColors();
SetResourceDimensions();
MainPage = new AppShell();
}
protected override void OnStart()
{
AppCenter.Start("xx", typeof(Crashes), typeof(Push));
Analytics.TrackEvent(VersionTracking.CurrentVersion);
}
Although I don't see any error messages when it starts up I am concerned about the way this is coded as from what I can see the App constructor fires first followed by the OnStart().
So if this happens, how can VersionTracking work. Should that code not be in the OnStart and how about the additional code that I have which sets up the application?
Would appreciate any advice that people can offer about the use of AppCenter with Xamarin forms.
Answer
Yes, you can use Xamarin.Essentials.VersionTracking in the constructor of App.
Explanation
You are confusing three different SDKs: Xamarin.Essentials, Xamarin.Forms and AppCenter.
VersionTracking is an API in Xamarin.Essentials.
App is a subclass of the Xamarin.Forms.Application API.
AppCenter.Start is an API in the AppCenter
These are three independent SDKs and each can be used independently of the others.
Xamarin.Forms app startup flow is like : Native App Startup -> Xamarin.Forms.Application Startup
Your App class is instantiated only after Native app has finished loading.
As versioning is managed by native app, there is no problem in initialising VersionTracking in constructor, as Native app has fully loaded by this time.

How to hide TimePicker and DatePicker on lifecycle events in Xamarin Forms

I'm running into an issue on android where our TimePicker and DatePicker stay visible when we navigate OnPause(). We need to redirect our users back to the login screen when they background the application, but if the TimePicker or DatePicker is active when they do this it stays on the screen. It appears above the login screen and pressing cancel or ok crashes the app.
We are hooking into the native android lifecycle events (not just using Xamarins built in hooks) and we redirect OnResume(). I've tested this in a barebones app though and it still happens OnPause().
Here is our TimePicker causing us the issue:
<TimePicker x:Name="VitalTimePicker" HorizontalOptions="Fill" VerticalOptions="Fill" IsVisible="false" PropertyChanged="OnTimePickerPropertyChanged"/>
And here is an example of changing screens on a lifecycle event:
protected override void OnSleep()
{
App.Current.MainPage = new NavigationPage(new NotesPage());
}
Any ideas? I was thinking of clearing the Pickers but I can't seem to find how to do that
Edit
Just to add a little more context
The Application class (app.xaml.cs) has lifecycle hooks that we use to catch when our users background the app. In here we call MainPage = new NavigationPage(new LoginPage()); which takes the app back to the login page.
I've added
protected override void OnDisappearing()
{
VitalTimePicker.Unfocus();
VitalDatePicker.Unfocus();
}
to the view i'm working from and it seems to be called when we background the application, but for some reason the TimePicker is staying on the screen when our login page pops up again.
You can programmatically close DatePickers and TimePickers using the method Unfocus(). I'd recommend closing them before you call the next page, as I don't know if they will be able to be referenced and closed after the other screen has been initialized.
Create a method that calls VitalTimePicker.Unfocus() and the same for any other picker you have, and call this method before changing to login screen and you should be good to go.

Error while leaving my application xamarin forms android in the background

My solution when I leave the application or leave it in the background gives an error 'The test application stopped', I can not find out where this queue comes from. Does anyone know where this trigger comes from the moment it leaves in the background
Is it something in this part of the code?
protected override void OnStart()
{
Debug.WriteLine("OnStart");
}
protected override void OnResume()
{
Debug.WriteLine("OnResume");
}
protected override void OnSleep()
{
Debug.WriteLine("OnSleep");
}
This type of errors came along with a specific part of your code, like #apineda mentioned maybe you are using an Android service that is updating some data on your application or it may be there to show a local notification who knows? but the thing I want to imply is that you need to take a look at your code and investigate further which is the part that is making the crash. Here are some tips:
1.- If you are using push notifications that may lead to something!
2.- Check you MainActivity.cs class since this is the one responsible of the Xamarin.Forms activity life cycle.
3.- If you have any timers on your shared code or even a background Task created with Task.Run or a Task.Factory.StartNew() check those too, deadlocks on Xamarin.Forms applications between the UI thread and background threads are a common thing on Xamarin.Forms.
I hope this helps!

Resources