告警管理器在服务中异常重复

Alarm Manager repeat abnormally with in Service

我创建了必须每隔一秒记录一次的简单服务。我使用了警报管理器(因为来自 official documentNote: The Alarm Manager is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running.)但它随机重复。 这是我的代码

MainActiviry.class

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

       FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        if (fab != null) {
            fab.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Intent intent = new Intent(MainActivity.this,LogService.class);
                    startService(intent);
                }
            });
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

我通过点击 FAB 按钮启动服务。

LogService.class

public class LogService extends Service {
    private static final String TAG = LogService.class.getSimpleName();

    public LogService() {
        super();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand: Service calling" );

        return super.onStartCommand(intent, flags, startId);
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onCreate() {
        Timer(this);
        super.onCreate();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private void Timer(Context context){
        Intent  intent = new Intent(context,LogService.class);
        PendingIntent pendingIntent = PendingIntent.getService(context,0,intent,0);
        AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(getApplicationContext().ALARM_SERVICE);
        alarmManager.setRepeating(alarmManager.RTC_WAKEUP,System.currentTimeMillis(),1*1000,pendingIntent);
    }
}

这是我的LOG

它每分钟都在重复,但我每秒都在写。我做错了吗?

因为 API 19 次重复警报 不准确 。看到这个:

Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.

您必须将 targetSdkVersion 设置为低于 19 的值,或者使用一次性精确警报并每次都重新设置它们。

这是official documentation

使用 java.util.Timer

的简单解决方案
Timer timer = new Timer();
            timer.scheduleAtFixedRate(new TimerTask() {

                @Override
                public void run() {
                    //Put your code here
                    Log.d("Log", "Hello World");
                }
            }, 0, 1000);