2017-08-30 35 views
3

对于我在学习xamarin期间的第一个项目,我制作了一个简单的应用程序,用户可以创建一个笔记并添加闹钟时间来安排本地通知。 我的应用程序从后台恢复时出现问题。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); 
    }   
} 

而当用户点击切换此功能工作正常。

下一点。

In MainPage.cs in function OnAppearing app fired function DataBaseService.checkNoteAlarmTimeActive();。在这个功能的应用程序检查AlarmTime在笔记中。如果AlarmTimeActive处于活动状态,但计划时间已过,则将AlarmTimeActive更改为“false”。

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

因此,应用程序从数据库中获取数据库中的第一次更新记录之前。

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”,用户点击“Home”按钮,app进入后台。稍后,当日程安排警报时间过去后,用户通过点击应用程序切换按钮下方的应用程序将应用程序置于前台。由于某种原因,应用程序首先显示警报“时间消逝”,后者(我认为)功能OnAppearing()。最后,在主页面中,我有一个包含更新记录的Notes列表,但为什么应用程序首先显示此警报?

但是在其他三种情况下不会出现此问题。
用户停用应用程序切换器列表中的应用程序,然后再次在应用程序列表中打开点击图标。
用户从应用程序点击退出后退按钮。
用户通过点击通知恢复应用程序。

那么,为什么如果用户从应用程序切换器列表恢复应用程序,此警报显示,但在其他情况下不显示?

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

回答

1

尽量避免async void,除了事件处理程序。 OnAppearing不是一个事件处理程序。但它是在实际的Appearing事件之前调用的,它让您有机会使用实际的事件处理程序来订阅它,以便您可以正确使用异步/等待。

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); 
} 

调用构造函数需要重构出到这个事件处理为好。

+0

对不起,但没有帮助。效果相同。我也重构了构造函数。 – Klick

相关问题