如何解决Tizen Watch App中的不确定错误
我正在尝试为Samsung galaxy Watch创建一个简单的计数器应用程序,该应用程序可响应边框并具有加/减按钮以分别增加/减少计数器。当计数器值低于某些阈值时,其颜色应更改(例如,当它接近0时,从白色变为橙色再变为红色)。这些按钮应该能够保持按下状态,以使计数器在稍稍延迟直到松开之前迅速增加/减少。此功能通常有效,除了按下按钮时有时会出现不确定性错误。通过检查我的代码,应该没有任何问题,但是也许我遗漏了一些东西。这是一个复制问题的SCCM:
using System;
using System.Collections.Generic;
using System.Timers;
using Tizen.Wearable.CircularUI.Forms;
using Xamarin.Forms;
namespace RepeatableCounter
{
class Program : global::Xamarin.Forms.Platform.Tizen.FormsApplication
{
protected override void OnCreate()
{
base.OnCreate();
LoadApplication(new App());
}
static void Main(string[] args)
{
var app = new Program();
Forms.Init(app);
global::Tizen.Wearable.CircularUI.Forms.FormsCircularUI.Init();
app.Run(args);
}
}
class App : Application
{
public App()
{
MainPage = new MainPage { Value = 20,Thresholds = { (5,Color.Red),(10,Color.Orange) }};
}
}
class MainPage : BezelInteractionPage,IRotaryEventReceiver
{
private int value;
private int ticks;
private readonly Label counter;
private readonly Timer resetTicks;
public MainPage() : base()
{
value = 0;
ticks = 0;
counter = new Label
{
Text = value.ToString(),FontSize = 32,BackgroundColor = Color.Transparent,HorizontalTextAlignment = TextAlignment.Center
};
RepeatButton plusButton = new RepeatButton
{
Text = "+",Delay = 500,Interval = 100,HorizontalOptions = Layoutoptions.Center,WidthRequest = 60
};
RepeatButton minusButton = new RepeatButton
{
Text = "\u2212",WidthRequest = 60
};
Content = new StackLayout
{
VerticalOptions = Layoutoptions.Center,Spacing = -24,Children = {
plusButton,counter,minusButton
}
};
RotaryFocusObject = this;
resetTicks = new Timer
{
Interval = 500,Enabled = false,AutoReset = false,};
resetTicks.Elapsed += (sender,e) => ticks = 0;
plusButton.pressed += (sender,e) => Value++;
plusButton.Held += (sender,e) => Value++;
minusButton.pressed += (sender,e) => Value--;
minusButton.Held += (sender,e) => Value--;
}
public int Value
{
get { return value; }
set
{
this.value = value;
counter.Text = this.value.ToString();
Color selected = Color.Default;
foreach ((int threshold,Color color) in Thresholds)
{
if (value <= threshold)
{
selected = color;
break;
}
}
counter.TextColor = selected;
}
}
public int TickThreshold { get; set; } = 10;
public int FastTickStep { get; set; } = 5;
public IList<(int,Color)> Thresholds { get; set; } = new List<(int,Color)>();
public void Rotate(RotaryEventArgs args)
{
if (args.IsClockwise)
{
if (ticks >= 0)
ticks++;
else
ticks = 1;
if (ticks <= TickThreshold)
Value++;
else
Value += FastTickStep;
}
else
{
if (ticks <= 0)
ticks--;
else
ticks = -1;
if (ticks >= -TickThreshold)
Value--;
else
Value -= FastTickStep;
}
resetTicks.Stop();
resetTicks.Start();
}
}
public class RepeatButton : Button
{
private readonly Timer timer;
public RepeatButton() : base()
{
timer = new Timer
{
Enabled = false,AutoReset = true
};
timer.Elapsed += (sender,e) => {
timer.Interval = Interval;
Held.Invoke(timer,e);
};
pressed += (sender,e) => {
timer.Interval = Delay;
timer.Start();
};
Released += (sender,e) => timer.Stop();
}
public double Delay { get; set; } = 100;
public double Interval { get; set; } = 100;
public event EventHandler Held;
}
}
要复制问题,请按住+
和/或-
按钮。由于问题不是确定性的,因此您可能偶尔需要切换按钮。我大多数时候都看到它是在颜色改变后发生的。
我遇到了三个“症状”:
添加更多UI元素似乎加剧了该问题并导致错误发生得更快,并且这在模拟器和实际手表中均会发生。我缺少某种同步或线程问题吗?是什么原因导致这些错误?
解决方法
请使用Device.StartTimer
代替System.Threading.Timer
。
System.Threading.Timer
使用辅助线程,因此它不应直接访问UI
要在UI线程上执行代码,可以使用Device.BeginInvokeOnMainThread
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。