【问题标题】:Xamarin. Different behavior app after resume赛马林。恢复后不同的行为应用程序
【发布时间】:2017-09-01 04:20:07
【问题描述】:

对于我在学习 xamarin 期间的第一个项目,我制作了一个简单的应用程序,用户可以在其中创建注释并添加闹钟时间以安排本地通知。 应用从后台恢复时出现问题。

直截了当。

笔记模型:

public class Note
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    [MaxLength(255)]
    public string Title { get; set; }
    [MaxLength(255)]
    public string Content { get; set; }

    public DateTime TimeCreate { get; set; }
    public DateTime AlarmTime { get; set; }
    public bool AlarmTimeActive { get; set; }
}

在主页有笔记列表。每个音符都有一个开关按钮,用户可以在其中打开/关闭时间警报。 如果用户尝试打开警报,则功能检查是否已安排时间。如果消失了,则开关保持在关闭位置并应用显示信息。在其他情况下,函数将数据库中的值更新为“true”。

XAML

<local:ButtonActiveSwitcher Toggled="Switch_Toggled" IsToggled="{Binding AlarmTimeActive}" Active="{Binding .}" />

函数“Switch_Toggled”

private void Switch_Toggled(object sender, ToggledEventArgs e)
{    
    var switchBtn = sender as Switch;

    var item = ((ButtonActiveSwitcher)sender).Active;          
    if (item != null)
    {
        if (item.AlarmTime < DateTime.Now)
        {
            if (_nooLoopTime.AddSeconds(2) < DateTime.Now) //Prevent double display alert
            {
                DisplayAlert("ALERT", "Time gone", "OK");
                _nooLoopTime = DateTime.Now;
            }                    
            switchBtn.IsToggled = false;
            return;
        }                
        DataBaseService.updateRecord(item);
    }           
}

当用户点击切换器时,此功能可以正常工作。

下一点。

MainPage.cs 中的函数 OnAppearing 应用程序触发函数 DataBaseService.checkNoteAlarmTimeActive();。在此功能应用程序中检查注释中的AlarmTime。如果AlarmTimeActive 处于活动状态但计划时间已经过去,则将AlarmTimeActive 更改为“false”。

第一个应用程序检查数据库中的笔记并更新它们,下一个函数loadNotes() 从数据库中获取笔记并填充列表。

所以在应用从 DB 获取 Notes 之前首先更新 DB 中的记录。

MainPage.cs

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MainPage : ContentPage
{
    private Sorting _sorting;
    private int _sortOption;
    private bool _activeSwitcherState;
    private DateTime _nooLoopTime;


    public MainPage(int noteid)
    {
        DataBaseService.CreateTables();            
        this._sorting = new Sorting();                     

        InitializeComponent();
        this.AddPickerItems();
        if (noteid != 0)
        {
            this.loadNoteView(noteid);
        }
    }

    protected async override void OnAppearing()
    {          
        await DataBaseService.checkNoteAlarmTimeActive();
        this.loadNotes();                       
        base.OnAppearing();
    }

    /// <summary>
    /// Generate list of notes basic on current sorting option and active switcher
    /// </summary>     
    private async void loadNotes()
    {
        listNotes.ItemsSource = await _sorting.sortNotes(_sortOption, _activeSwitcherState);          
    }
}

这是我的问题。

例如:一个笔记有AlarmTimeActive“true”并且用户点击了“主页”按钮,应用程序进入后台。稍后,当计划闹钟时间已经过去时,用户通过从应用程序切换器按钮下的列表中点击应用程序将应用程序置于前台。出于某种原因,应用程序首先显示警报“时间已逝”,而后者(我认为)确实起作用OnAppearing()。最后在主页中,我有一个带有更新记录的笔记列表,但为什么应用程序首先显示此警报?

但是这个问题在其他三种情况下都没有出现。
用户在 App Switcher 列表中终止应用,然后在应用列表中点击图标再次打开。
用户从应用退出时点击了返回按钮。
用户通过点击通知恢复应用程序。

那么为什么如果用户从 App Switcher 列表中恢复应用,会显示此警报,但在其他情况下不显示?

我希望我的描述很清楚。 请向我解释为什么会发生这种情况以及如何解决。

【问题讨论】:

    标签: c# xamarin xamarin.android onresume


    【解决方案1】:

    尽量避免使用async void,事件处理程序除外。 OnAppearing 不是事件处理程序。但它是在实际的 Appearing 事件之前调用的吗,这使您有机会使用实际的事件处理程序订阅它,从而使您可以正确使用 async/await。

    protected override void OnAppearing() {
        this.Appearing += Page_Appearing;                    
        base.OnAppearing();
    }
    
    private async void Page_Appearing(object sender, EventArgs e) {
        //...call async code here
        await DataBaseService.checkNoteAlarmTimeActive();
        var notes = await loadNotes();
        listNotes.ItemsSource = notes;
        //unsubscribing from the event (optional but advised)
        this.Appearing -= Page_Appearing;
    }
    
    /// <summary>
    /// Generate list of notes basic on current sorting option and active switcher
    /// </summary>     
    private Task<IEnumerable<Note>> loadNotes()
    {
        return _sorting.sortNotes(_sortOption, _activeSwitcherState);          
    }
    

    我大概猜到这段代码...

    if (noteid != 0)
    {
        this.loadNoteView(noteid);
    }
    

    在构造函数中调用也应该重构到事件处理程序中。

    【讨论】:

    • 抱歉,没有帮助。同样的效果。我也重构了构造函数。
    猜你喜欢
    • 2014-08-11
    • 1970-01-01
    • 2019-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-17
    • 1970-01-01
    相关资源
    最近更新 更多