gpt4 book ai didi

c# - AlarmManager.SetRepeating 无法正常工作

转载 作者:行者123 更新时间:2023-11-30 23:28:49 26 4
gpt4 key购买 nike

我试图通过 AlarmManager 定期调用一个线程。问题是,在给定的时间段之后,OnReceive() 被调用了两次(为什么?),然后再也没有调用过。我在这里做错了什么?
我在 API 级别 23 上使用适用于 Android 的 Xamarin (C#)。

MainActivity 中的代码:

Alarm alarm = new Alarm ();
RegisterReceiver (alarm, new IntentFilter ("com.company.BROADCAST"));
alarm.SetAlarm(this);

报警类:

[BroadcastReceiver]
[IntentFilter(new string[] {"com.company.BROADCAST"})]
public class Alarm : BroadcastReceiver
{
public override void OnReceive(Context c, Intent i)
{
Toast.MakeText (c, "hi", ToastLength.Short).Show ();
}

public void SetAlarm(Context context)
{
AlarmManager am = (AlarmManager)context.GetSystemService(Context.AlarmService);
Intent i = new Intent("com.company.BROADCAST");
PendingIntent pi = PendingIntent.GetBroadcast(context, 0, i, 0);
am.SetRepeating(AlarmType.ElapsedRealtimeWakeup, SystemClock.ElapsedRealtime() + 1000, 1000 * 2, pi);
}
}

最佳答案

OnReceive 被调用两次,因为您不小心将闹钟注册了两次。让我们将以下代码 fragment 添加到您的 Alarm 类中:

[BroadcastReceiver]
[IntentFilter(new string[] {"com.company.BROADCAST"})]
public class Alarm : BroadcastReceiver
{

public Alarm ()
: base()
{
Console.WriteLine ("Alarm made: " + this.GetHashCode ());
}

public Alarm(System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer)
: base(handle, transfer)
{
Console.WriteLine ("Alarm made: " + this.GetHashCode ());
}

// ...
}

如果我们运行应用程序,Alarm 将为每个创建的实例记录一个唯一的哈希码。因此,启动应用程序并观察应用程序输出中发生的情况:

Alarm made: 123719217
...
Alarm made: 119997678

哇哦!我们有 2 个实例...那是怎么发生的?

属性 [IntentFilter(new string[] {"com.company.BROADCAST"})] 为您的 Alarm : BroadcastReceiver 生成 list 条目,这将导致它自动收听 com.company.BROADCAST 的广播。 Xamarin 文档有很好的解释 here .

第二次注册发生在您在 Activity 中调用 RegisterReceiver 时。这会注册一个新的、唯一的 Alarm 实例来监听 com.company.BROADCAST 的广播。

您可以通过从 Alarm 或删除 Activity 中的 RegisterReceiver 调用。


其次,2000 毫秒对于 AlarmManager 来说太小了。它会自动将其延长至 60 秒以延长电池生命周期。

如果您运行示例并使用 logcat 捕获系统输出,您将看到一条消息来确认这一点:

W/AlarmManager(  579): Suspiciously short interval 2000 millis; expanding to 60 seconds

如果你想如此频繁地重复一个操作,考虑使用定时器或后延迟处理程序:

// Frequent operation using .NET Timer.
System.Timers.Timer t = new System.Timers.Timer (1000);
t.AutoReset = true;
t.Elapsed += (object sender, System.Timers.ElapsedEventArgs e) => {
t.Interval = 2000;
RunOnUiThread (() => Toast.MakeText (this, "Hi", ToastLength.Short).Show ());
};
t.Start ();

// Frequent operation using Android.OS.Handler
handler = new Handler ();
Action callback = null;
callback = () => {
//Do something after 100ms
Toast.MakeText(this, "Hi", ToastLength.Short).Show();
handler.PostDelayed(callback, 2000);
};
handler.PostDelayed(callback, 1000);

关于c# - AlarmManager.SetRepeating 无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35830784/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com