Xamarin Forms: 从后台恢复时应用始终重新启动

huangapple go评论56阅读模式
英文:

Xamarin Forms: App is always restarting when resuming from background

问题

"datepicker" UI出现了问题,并且显示在闪屏背景之上,如下所示:

代码:

<DatePicker
    x:Name="startdate_datepicker"
    Grid.Column="1"
    Format="MM/dd/yyyy"
    PropertyChanged="StartDateChoosed"
    HorizontalOptions="StartAndExpand"
    VerticalOptions="Center"/>

我的样式:

<style name="MainTheme" parent="MainTheme.Base">
    <item name="android:forceDarkAllowed">false</item>
    <item name="android:windowBackground">@drawable/splashscreen</item>
    <item name="android:textAllCaps">false</item>
    <item name="colorPrimary">#e6e6e6</item>
    <item name="colorPrimaryDark">#000000</item>
    <item name="colorAccent">#808080</item>
</style>

为了解决这个问题,我对"Style"和"MainActivity"进行了一些更新。

创建了一个新的闪屏样式:

<style name="MyTheme.Splash" parent="Theme.AppCompat.Light">
    <item name="android:forceDarkAllowed">false</item>
    <item name="android:windowBackground">@drawable/splashscreen</item>
    <item name="android:textAllCaps">false</item>
    <item name="colorPrimary">#e6e6e6</item>
    <item name="colorPrimaryDark">#000000</item>
    <item name="colorAccent">#808080</item>
</style>

<style name="MyTheme.Main" parent="MainTheme.Base">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <item name="android:forceDarkAllowed">false</item>
    <item name="android:textAllCaps">false</item>
    <item name="colorPrimary">#e6e6e6</item>
    <item name="colorPrimaryDark">#000000</item>
    <item name="colorAccent">#808080</item>
</style>

MainActivity:

[Activity(
    Label = "App Name", 
    Theme = "@style/MyTheme.Main", 
    Icon = "@drawable/launcher_icon", 
    MainLauncher = false,
    NoHistory = true,
    Exported = true,
    ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation, 
    ScreenOrientation = ScreenOrientation.Portrait)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState, persistentState);
    }
}

[Activity(
    Theme = "@style/MyTheme.Splash",
    MainLauncher = true,
    NoHistory = true,
    ScreenOrientation = ScreenOrientation.Portrait)]
public class SplashActivity : AppCompatActivity
{
    public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
    {
        base.OnCreate(savedInstanceState, persistentState);
    }

    protected override void OnResume()
    {
        base.OnResume();
        var startUp = new Task(() =>
        {
            var intent = new Intent(this, typeof(MainActivity));
            StartActivity(intent);
        });
        startUp.ContinueWith(t => Finish());
        startUp.Start();
    }
}

但现在,我的应用在从后台恢复时总是重新启动,这是因为"MainActivity"中的"OnResume()"代码。如果我要从后台恢复并保持在同一页上,我需要在"SplashActivity"上做哪些改变?

英文:

The datepicker UI is breaking and it is showing on top of the splash screen background like below:

Xamarin Forms: 从后台恢复时应用始终重新启动

Code:

&lt;DatePicker
	x:Name=&quot;startdate_datepicker&quot;
	Grid.Column=&quot;1&quot;
	Format=&quot;MM/dd/yyyy&quot;
	PropertyChanged=&quot;StartDateChoosed&quot;
	HorizontalOptions=&quot;StartAndExpand&quot;
	VerticalOptions=&quot;Center&quot;/&gt;

My Style:

&lt;style name=&quot;MainTheme&quot; parent=&quot;MainTheme.Base&quot;&gt;
	&lt;item name=&quot;android:forceDarkAllowed&quot;&gt;false&lt;/item&gt;
	&lt;item name=&quot;android:windowBackground&quot;&gt;@drawable/splashscreen&lt;/item&gt;
	&lt;item name=&quot;android:textAllCaps&quot;&gt;false&lt;/item&gt;
	&lt;item name=&quot;colorPrimary&quot;&gt;#e6e6e6&lt;/item&gt;
	&lt;item name=&quot;colorPrimaryDark&quot;&gt;#000000&lt;/item&gt;
	&lt;item name=&quot;colorAccent&quot;&gt;#808080&lt;/item&gt;

For solving this issue I made some updates on Style and MainActivity.

Created a new style for splash:

&lt;style name=&quot;MyTheme.Splash&quot; parent=&quot;Theme.AppCompat.Light&quot;&gt;
	&lt;item name=&quot;android:forceDarkAllowed&quot;&gt;false&lt;/item&gt;
	&lt;item name=&quot;android:windowBackground&quot;&gt;@drawable/splashscreen&lt;/item&gt;
	&lt;item name=&quot;android:textAllCaps&quot;&gt;false&lt;/item&gt;
	&lt;item name=&quot;colorPrimary&quot;&gt;#e6e6e6&lt;/item&gt;
	&lt;item name=&quot;colorPrimaryDark&quot;&gt;#000000&lt;/item&gt;
	&lt;item name=&quot;colorAccent&quot;&gt;#808080&lt;/item&gt;
&lt;/style&gt;

&lt;style name=&quot;MyTheme.Main&quot; parent =&quot;MainTheme.Base&quot;&gt;
	&lt;item name=&quot;windowActionBar&quot;&gt;false&lt;/item&gt;
	&lt;item name=&quot;windowNoTitle&quot;&gt;true&lt;/item&gt;
	&lt;item name=&quot;android:forceDarkAllowed&quot;&gt;false&lt;/item&gt;
	&lt;item name=&quot;android:textAllCaps&quot;&gt;false&lt;/item&gt;
	&lt;item name=&quot;colorPrimary&quot;&gt;#e6e6e6&lt;/item&gt;
	&lt;item name=&quot;colorPrimaryDark&quot;&gt;#000000&lt;/item&gt;
	&lt;item name=&quot;colorAccent&quot;&gt;#808080&lt;/item&gt;
&lt;/style&gt;

MainActivity:

[Activity(
	Label = &quot;App Name&quot;, 
	Theme = &quot;@style/MyTheme.Main&quot;, 
	Icon = &quot;@drawable/launcher_icon&quot;, 
	MainLauncher = false,
	NoHistory = true,
	Exported =true,
	ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation, 
	ScreenOrientation = ScreenOrientation.Portrait)]

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
	protected override void OnCreate(Bundle savedInstanceState)
	{
		base.OnCreate(savedInstanceState, persistentState);
	}
}

[Activity(
		Theme = &quot;@style/MyTheme.Splash&quot;,
		MainLauncher = true,
		NoHistory = true,
		ScreenOrientation = ScreenOrientation.Portrait)]
public class SplashActivity : AppCompatActivity
{
	public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
	{
		base.OnCreate(savedInstanceState, persistentState);
	}

	protected override void OnResume()
	{
		base.OnResume();
		var startUp = new Task(() =&gt;
		{
			var intent = new Intent(this, typeof(MainActivity));
			StartActivity(intent);
		});
		startUp.ContinueWith(t =&gt; Finish());
		startUp.Start();
	}
}

But now my app is always restarting when resuming from background due to the OnResume() code in SplashActivity. I need to stay on the same page if I resume from background. For that What change I need to do on SplashActivity?

答案1

得分: 0

根据Xamarin.Forms关于应用程序生命周期方法的文档,您可以使用OnSleepOnResume方法。

  • OnSleep - 每次应用程序进入后台时调用。

  • OnResume - 当应用程序从后台恢复时调用。

以下是您可以参考的演示:

protected override void OnSleep()
{
    // 保存当前页面状态
    var currentPage = Application.Current.MainPage as NavigationPage;
    var state = currentPage.CurrentPage.BindingContext;
    Application.Current.Properties["CurrentPageState"] = state;
}

protected override void OnResume()
{
    // 检索已保存的页面状态并设置页面属性
    if (Application.Current.Properties.ContainsKey("CurrentPageState"))
    {
        var state = Application.Current.Properties["CurrentPageState"];
        var currentPage = Application.Current.MainPage as NavigationPage;
        currentPage.CurrentPage.BindingContext = state;
    }
}
英文:

According to the Xamarin.Forms documentation on app lifecycle methods, you can use the OnSleep and OnResume methods

  • OnSleep - called each time the application goes to the background.

  • OnResume - called when the application is resumed, after being sent
    to the background.

Here is the demo you can refer to:

protected override void OnSleep()
{
    // Save the current page state
    var currentPage = Application.Current.MainPage as NavigationPage;
    var state = currentPage.CurrentPage.BindingContext;
    Application.Current.Properties[&quot;CurrentPageState&quot;] = state;
}

protected override void OnResume()
{
    // Retrieve the saved page state and set the page properties
    if (Application.Current.Properties.ContainsKey(&quot;CurrentPageState&quot;))
    {
        var state = Application.Current.Properties[&quot;CurrentPageState&quot;];
        var currentPage = Application.Current.MainPage as NavigationPage;
        currentPage.CurrentPage.BindingContext = state;
    }
}

答案2

得分: 0

问题是在从后台恢复应用程序时,调用恢复方法时重新创建了 MainActivity 导致的。

[Activity(Label = "移动应用程序",
    Theme = "@style/Your_Splash_Theme",
    Icon = "@drawable/Your_Icon",
    MainLauncher = true,
    ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation,
    LaunchMode = LaunchMode.SingleTop)]

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.Window.RequestFeature(WindowFeatures.ActionBar);
        // 在这里之前的 MainActivity 主题的名称。
        base.SetTheme(Resource.Style.MainTheme);
        base.OnCreate(savedInstanceState);

        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
        LoadApplication(new App());
    }
    // 其他方法
}
英文:

The issue is caused by recreating the MainActivity when calling the resume method when restoring the app from the background.

[Activity(Label = &quot;Mobile App&quot;,
		Theme = &quot;@style/Your_Splash_Theme&quot;,
		Icon = &quot;@drawable/Your_Icon&quot;,
		MainLauncher = true,
		ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation,
		LaunchMode = LaunchMode.SingleTop)]

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
	protected override void OnCreate(Bundle savedInstanceState)
	{
		base.Window.RequestFeature(WindowFeatures.ActionBar);
		// Name of the MainActivity theme you had there before.
		base.SetTheme(Resource.Style.MainTheme);
		base.OnCreate(savedInstanceState);

		Xamarin.Essentials.Platform.Init(this, savedInstanceState);
		global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
		LoadApplication(new App());
	}
// other methods
}

huangapple
  • 本文由 发表于 2023年6月12日 18:33:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76455785.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定