我有一个Android Widget按钮,当按下插入记录到SQLite数据库
当应用程序在这种情况下使用时,我有一个问题:
- 用户暂停应用程序以在其设备主屏幕上使用小部件。
- 用户按小部件按钮插入新记录。
- 用户恢复Xamarin。表单页面。
当页面恢复时,onappear自动被调用。但是,内容没有更新。当UpdateDailyCount()
被正确调用时,labelDailyCount
应该被更新以显示新的每日计数。
记录被正确插入到数据库中(当移动到另一个页面,然后返回到主页时,记录被显示)。当用户暂停应用程序时,计时器继续运行,但在恢复页面时,UI不更新。
如果我将Device.BeginInvokeOnMainThread(() => UpdateDailyCount());
放在Device.BeginInvokeOnMainThread(() => CalculateTimeDifference());
之后,那么UI将正确更新,但这并不理想,因为UpdateDailyCount()
将每秒被调用。
private Book latestBook;
protected override void OnAppearing()
{
base.OnAppearing();
latestBook = App.Database.GetRecentBookDate().FirstOrDefault();
UpdateDailyCount();
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
Device.BeginInvokeOnMainThread(() => CalculateTimeDifference());
return true;
});
}
void BtnAdd_Clicked(object sender, EventArgs e) {
Book book = new Book
{
BookSaveTime = DateTime.Now
};
App.Database.SaveBook(book);
latestBook = book;
}
void CalculateTimeDifference() {
if (latestBook == null)
{
this.labelTimeSince.Text = "-";
}
else
{
var timeDifference = DateTime.Now - latestBook.BookSaveTime;
this.labelTimeSince.Text = timeDifference.ToString("HH:mm:ss");
}
}
void UpdateDailyCount() {
int dailyCount = App.Database.GetDailyCount();
this.labelDailyCount.Text = dailyCount.ToString();
}
为什么是labelDailyCount。当页面恢复时,文本未更新-尽管UpdateDailyCount()
被正确调用。
答案
当用户从后台恢复应用程序时,ContentPage.OnAppearing
不会触发。
当用户从后台恢复应用程序时,你需要重写Application.OnResume
来处理事件:
public class App : Application
{
// ...
protected override async void OnResume()
{
base.OnResume();
// Handle app resuming from background
}
// ...
}
解决方案我建议在Application
中创建一个Resumed
事件,然后你可以从任何ContentPage
订阅它。
public class App : Application
{
// ...
public static event EventHandler Resumed;
protected override async void OnResume()
{
base.OnResume();
Resumed?.Invoke(this, EventArgs.Empty);
}
// ...
}
class BookPage : ContentPage
{
public BookContentPage()
{
InitializeComponent();
App.Resumed += HandleResumed;
}
void HandleResumed(object sender, System.EventArgs e)
{
latestBook = App.Database.GetRecentBookDate().FirstOrDefault();
UpdateDailyCount();
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
Device.BeginInvokeOnMainThread(() => CalculateTimeDifference());
return true;
});
}
}