Each phone has its own sleep policy, Android
the phone does not operate in a long time so that CPU will automatically go to sleep, which leads to JAVA native Timer
timed task can not run.
So we need to help Alarm
wake up the CPU
First, the Alarm
mechanism
Alarm With the AlermManager
class, and NotificationManger
similar. By calling Context
in getSystemService()
to obtain an instance, but here to be passed Context..ALARM_SERVICE
, therefore, get AlarmManager
examples can be written as:
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
The next call to AlertManager
the set()
method can be provided a timed task, such as task execution after 10 seconds:
long triggerAtTime = SystemClock.elapsedRealtime() + 10*1000;
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pendingIntent);
SystemClock.elepsedRealtime()
The system can obtain the number of milliseconds since the start
System.cuurrentTimeMillis()
number of milliseconds since 1970.1.1 may be acquired
set()
method takes three parameters:
- The first parameter: integer parameter that specifies the type of work, there are four selectable values:
ELAPSED_REALTIME
: Trigger time since the beginning of the regular tasks of the boot, but would not wake up the CPUELAPSED_REALTIME_WAKEUP
: Trigger time counted from the regular tasks of system boot begins, wake up the CPURTC
: Trigger time from the start of the regular tasks 1970.1.1 date, but will not wake up the CPURTC_WAKEUP
Triggering Event: 1970.1.1 regular tasks from the start date, but will wake up the CPU
- The second argument: the task trigger time, in milliseconds
- The third parameter
PendingIntent
broadcast or services, can trigger a
Another example may be a long time to achieve a timed run in the background of the service:
first of all to build a common service, such as named LongRunningService
, then the code written on the trigger timing tasks onStartCommand()
:
public class LongRunningService extends Service{
@Override
public IBinder onBind(Intent intent){
return null;
}
@Overide
public int onStartCommand(Intent intent, int flags, int startId){
new Thread(new Runnable(){
@Override
public void run(){
// 在这里执行具体的逻辑事件
}
}).start();
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
int anHour = 60*60*1000;
long triggerAtTime = SystemClock.elapsedRealtime()+anHour();
Intent i = new Intent(this, LongRunningService.class);
PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
return super.onStartCommand(intent, flags, startId);
}
}
This ensures that every hour timer in order to perform a task, and finally, so start the scheduled task:
Intent intent = new Intent(context, LongRunningService.class);
context.startService(intent);
After Androiod4.4, trigger time Alarm task is no longer accurate, this is a system made to optimize power consumption, using setExact()
instead of set()
to run on time
Second, the Doze
model
After Android 6.0, Google has added a new Doze mode, that is, when the screen turns off after a period of time, the system will CPU, network, Alarm and other activities to make restrictions, thus extending battery life
but the system intermittently exit Doze
mode short time for the application to complete their task synchronization and Alerm.
Specific restrictions:
- Network access is prohibited
- Ignore wake up the CPU and screen operations
- No wifi scanning
- No longer perform synchronization tasks
- Alarm task will be executed when the next exit Doze mode
This makes our task Alarm longer time, but if you have to perform on time, there are also special programs:
AlarmManager.setAndAllowWhileIdle()
or AlermManager,setExactAndAllowWhileIdle()
make Doze mode can also perform regular tasks properly, use and prior to setExact()
or set()
the same as