Reputation: 610
If I navigate in my App and go back to the Android LaunchScreen with the HomeButton the OnSleep() Hook is called, which is fine. If I navigate back into the App using the Android TaskManager OnResume() is called. If I navigate in my App with the Hardware BackButton then also OnSleep() is called which is fine, but if I navigate back into my app then the OnCreate Method in the MainActivity is called which recreated the App.
global::Xamarin.Forms.Forms.Init (this, bundle);
DisplayCrashReport();
LoadApplication (new Gtue.Mobile.App ());
That should not happen. In the ctor of App.xaml I initialize stuff which only should be initialized once. I tried every LaunchMode for the MainAcitivity, nothing helped.
Is there a way to find out if the App was already initialized?
Upvotes: 2
Views: 1048
Reputation: 2601
I came across this issue when observing my App.xaml.cs constructor was being called when I was pressing the home button on my Android device and then clicking my app.
The well detailed answer above details the correct "anticipated behaviour", but this was not the case for me.
I was getting this kind of flow when using the home button or back button -
**On Debug Start**
MainActivity:OnCreate
XF:AppCtor
XF:OnStart
MainActivity:OnResume
**Press Home Button**
MainActivity:OnPause
XF:OnSleep
**Launch App via Click on App Icon**
MainActivity:OnCreate
XF:AppCtor
Searching eventually led me to -
App restarts rather than resumes
Which in turn resulted in the following Xamarin code at the top of MainActivity OnCreate -
if (!IsTaskRoot)
{
string action = Intent.Action;
if (Intent.HasCategory(Android.Content.Intent.CategoryLauncher) &&
!string.IsNullOrEmpty(Intent.Action) &&
action == Android.Content.Intent.ActionMain)
{
Finish();
return;
}
}
Which seems to solve the initial reload at least.
I also combined this with -
LaunchMode = LaunchMode.SingleTask
To stop some double activity shenanigans when clicking on a notification in notification screen.
Upvotes: 0
Reputation: 9084
Your App
class extends from Xamarin.Forms.Application
and the Xamarin.Forms.Application
life cycle is bind with the Activity
life cycle. You could find it in the source code :
async Task OnStateChanged()
{
if (_application == null)
return;
if (_previousState == AndroidApplicationLifecycleState.OnCreate && _currentState == AndroidApplicationLifecycleState.OnStart)
_application.SendStart();
else if (_previousState == AndroidApplicationLifecycleState.OnStop && _currentState == AndroidApplicationLifecycleState.OnRestart)
_application.SendResume();
else if (_previousState == AndroidApplicationLifecycleState.OnPause && _currentState == AndroidApplicationLifecycleState.OnStop)
await _application.SendSleepAsync();
}
So you just need to care about your Activity
's life cycle. When you touch the HomeButton
your application don't remove the MainActivity
from the task's stack and the MainActivity
will be available when you re-enter the app, so it didn't execute the OnCreate
method.
When you touch the HomeButton
:
[0:] MainActivity OnPause
[0:] MainActivity OnStop
[0:] Forms App OnSleep
When you use the Android TaskManager
open your application :
[0:] MainActivity OnRestart
[0:] Forms App OnResume
[0:] MainActivity OnResume
But when you touch the hardware BackButton
, the MainActivity
will be removed from the task's stack :
[0:] MainActivity OnPause
[0:] MainActivity OnStop
[0:] Forms App OnSleep
[0:] MainActivity OnDestroy
When the MainActivity
is destoryed, your application will dispose resource and it including your Gtue.Mobile.App
instance. And you could see the source code about OnDestroy() method :
protected override void OnDestroy()
{
PopupManager.Unsubscribe(this);
_platform?.Dispose();
// call at the end to avoid race conditions with Platform dispose
base.OnDestroy();
}
So the next time when you open your application, it is necessary to recreated the App
class. Actually, the App
did only be initialized once.
Upvotes: 3