抖动android_alarm_manager插件未定期运行

ha5z0ras  于 2022-12-21  发布在  Android
关注(0)|答案(2)|浏览(109)

我试图在Flutter中创建后台计时器,每n秒调用一次。调用AndroidAlarmManager.periodic应该每2秒运行一次print("Hello")函数,但它看起来像是以更大的间隔随机调用的。我做错了什么?

import 'package:android_alarm_manager/android_alarm_manager.dart';

void runTimer()  async{
  await AndroidAlarmManager.periodic(const Duration(seconds: 2), 0, printHello, exact: true);
}

void printHello(){
  print("Hello");
}

main() async {
  await AndroidAlarmManager.initialize();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        body: Center(
          child: InkWell(
            onTap: runTimer,
            child: Container(child: Text('Run Timer'))
          ),
        ),
      ),
    );
  }
}
v6ylcynt

v6ylcynt1#

您不能使用AlarmManager频繁地安排闹钟:
注:从API 19(Build.VERSION_CODES.KITKAT)开始,报警输送不准确:操作系统将转移警报以减少唤醒和电池使用。有新的API来支持需要严格交付保证的应用程序;请参阅setWindow(int,long,long,android.app.PendingIntent)和setExact(int,long,android.app.PendingIntent)。targetSdkVersion早于API 19的应用程序将继续看到之前的行为,即所有报警都在请求时准确发送。
参见:https://developer.android.com/reference/android/app/AlarmManager

nzk0hqpo

nzk0hqpo2#

@kashlo,将以下代码添加到main()中

void funTimerMain() async  {

  // A few things that you can do with funTimerMain:

  // No 1. Do something you want, e.g.
  intCounter += 1;  // intCounter is a GLOBAL VARIABLE (Integer), which was initialized to 0
  print('intCounter: ' + intCounter.toString());

  // No 2. Use the following lines only if you use Redux to manage state
  // strCurPage is a GLOBAL VARIABLE (String) that stores which 'page' the user is currently navigating
  if (strCurPage == 'PageHome') {
    // storeHome is the Redux 'STORE' that keep track of the state of Page Home
    // The following line 'Refresh/Re-render' page Home (like a 'setState' in Page Home)
    // i.e. you can 'setState' page Home in an external event, like in this timer function
    storeHome.dispatch(Actions.Increment);
  }

  // No 3. Send a message to server every 5 seconds (Instead of 1 second!), using socket.io
  // timLastHeartBeat is a Global Variable (Integer) that was initialized to DateTime.now().millisecondsSinceEpoch;
  if (DateTime.now().millisecondsSinceEpoch - timLastHeartBeat > 5000) {
    socket.emit('HeartBeat', [intCounter]);
    timLastHeartBeat = DateTime.now().millisecondsSinceEpoch;
  }

  // recall this timer every 1 second
  new Future.delayed(new Duration(milliseconds: 1000), () async { 
    funTimerMain(); 
  }); 
}

// runApp!
runApp(MyApp());

// call the timer for the first time
funTimerMain();

问题1:funTimerMain中的编号1、2、3何时运行?当应用程序处于前台时(即用户使用应用程序),或当应用程序处于后台时(即用户按下主页按钮或切换到另一个应用程序)。
问题2:1、2号机组何时停止运行?答案2:当应用程序被用户或Android系统终止时(例如,被节电程序终止)
问题3:3号何时停止运行?回答3:与Ans 2相同,另外,当用户关闭屏幕时。从Android?开始(我忘记了确切的版本),当用户关闭屏幕时不允许网络访问。
如您所见,funTimerMain每1秒(或x秒)运行一次,但是funTimerMain中的每个任务可以每y秒运行一次(其中y〉= x,或者最好是y = Nx,N为整数)。
当我第一次使用这个技术的时候,我觉得效率会很糟糕,但是当我在真实的移动的上运行这个应用程序的时候,我注意不到手机上有任何延迟。所以我认为通过设置一个适当的x和y值,你可以有一个响应速度快的应用程序。
您也可以在funTimerMain中使用'await',但请记住,如果'function after await'没有返回,则计时器将暂停!

相关问题