2017-08-30 36 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

相關問題