[英]Why won't a toast notification appear in my background Service (using System.Timer)?
在后台服務中,我使用System.Timers創建一個倒數計時器。
它似乎起作用。 在控制台中2秒鍾后,我可以看到Console.WriteLine()打印文本。
但是,Toast通知沒有出現,我想知道為什么
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Media;
using Android.Content.Res;
using System.Timers;
namespace AudioTour
{
[Service(Exported = false, Name = "com.AudioTour.AudioService")]
public class AudioService : Service
{
// This method is called to start the Timer
private void StartCountdown()
{
RunTimer(2);
}
private Timer myTimer;
private int countDownSeconds;
// This is my timer
private void RunTimer(int _timerLength)
{
myTimer = new Timer();
myTimer.Interval = 1000;
myTimer.Elapsed += OnTimedEvent;
countDownSeconds = 5;
myTimer.Enabled = true;
}
// When the timer has elapsed this event is called
private void OnTimedEvent(object sender, System.Timers.ElapsedEventArgs elapsedEventArgs)
{
countDownSeconds--;
// This is what I expect to happen when the timer reaches 0
if (countDownSeconds == 0)
{
Console.WriteLine("Timer Finished");
Toast.MakeText(this, "Timer Finished", ToastLength.Short).Show();
myTimer.Stop();
}
}
Android中的后台服務沒有UI,因此它是UI組件,因此無法產生Toast。
@ jason.kaisersmith,大家好,我的看法有點不同,我認為吐司無法顯示是因為線程而不是Service
本身。
如文件所述,服務可以顯示Toast
:
可以通過“活動”或“服務”創建並顯示吐司。 如果您通過服務創建敬酒通知,它將顯示在當前關注的活動的前面。
為什么不能在此問題中顯示它? 注意, Toast.MakeText
方法:
這意味着如果要顯示吐司, 必須將吐司放在主線程上 ,我認為這是原因。 您的問題是OnTimedEvent
方法將在其他線程中運行,因此您在Android中不允許的線程中顯示Toast
。
如您所說, You simply initialize it, then it gets passed off to a system service queue
。 在Toast
源代碼中,我們可以證明您的意見:
//insert toast to a messagequeue
service.enqueueToast(pkg, tn, mDuration);
現在的問題變成了如何將此消息發送到Main thread 。
我們只需要在主線程的消息隊列中加入祝酒詞,Android就為我們提供了一個API Looper.getMainLooper()來實現此功能,並像這樣修改您的代碼:
private void OnTimedEvent(object sender, System.Timers.ElapsedEventArgs elapsedEventArgs)
{
countDownSeconds--;
// This is what I expect to happen when the timer reaches 0
if (countDownSeconds == 0)
{
Console.WriteLine("Timer Finished==========================");
Handler handler = new Handler(Looper.MainLooper);
//Returns the application's main looper, which lives in the main thread of the application.
Action myAction = () =>
{
Toast.MakeText(this, "Timer Finished", ToastLength.Short).Show();
};
handler.Post(myAction);
myTimer.Stop();
}
}
效果:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.