重复的服务设计Android
Repetitive service design Android
我的应用程序中有以下设计:我有一个 activity 设置重复警报,启动接收器来启动我的服务。每一分钟。在我的服务中,我设置了 Start Sticky,但是一旦 Android 决定终止我的服务,我就无法重新启动它。这是 Android 4.4.2。这是我的代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent i1 = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(MainActivity.this, 0, i1, PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, 0, 60 * 1000, pi);
}
这里是收件人
public void onReceive(Context arg0, Intent arg1) {
// For our recurring task, we'll just display a message
Log.d(Constants.TAG, "Starting Service");
Intent intent = new Intent(arg0, MyLocationService.class);
arg0.startService(intent);
}
和服务:
private static PowerManager.WakeLock wl;
private static OkHttpClient client;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(Constants.TAG, "Service onStartCommand");
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Constants.TAG);
wl.acquire();
client = new OkHttpClient();
new GetLocation(MyLocationService.this).execute();
return START_STICKY;
}
您很可能会看到与电源管理和警报的交互。以API 19 开头的所有警报默认情况下都是不精确,因此它们将与其他警报进行整理。此外,一旦设备进入低功耗状态,就会在 BroadcastReceiver
秒内发送警报,并且只要接收器正在执行其 onReceive()
方法,设备就会保证保持清醒。一旦它 returns 从该方法(以及与警报相关的任何其他 BroadcastReceiver
运行),设备将立即再次进入低功耗状态。由于您的应用程序之前已被终止,因此 Service
不再是 运行 并且不会获得 CPU 时间。
解决此问题的方法是使用 WakefulReceiver
,它在运行 onReceive()
时使用唤醒锁,启动您的 Service
进行处理。 Service
将在完成处理后释放唤醒锁。这篇文章会给你一个很好的解释:http://po.st/7UpipA
请注意,每分钟醒来一次会严重降低设备的电池寿命,因此您应该考虑取消此设置。
我的应用程序中有以下设计:我有一个 activity 设置重复警报,启动接收器来启动我的服务。每一分钟。在我的服务中,我设置了 Start Sticky,但是一旦 Android 决定终止我的服务,我就无法重新启动它。这是 Android 4.4.2。这是我的代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent i1 = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(MainActivity.this, 0, i1, PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, 0, 60 * 1000, pi);
}
这里是收件人
public void onReceive(Context arg0, Intent arg1) {
// For our recurring task, we'll just display a message
Log.d(Constants.TAG, "Starting Service");
Intent intent = new Intent(arg0, MyLocationService.class);
arg0.startService(intent);
}
和服务:
private static PowerManager.WakeLock wl;
private static OkHttpClient client;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(Constants.TAG, "Service onStartCommand");
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Constants.TAG);
wl.acquire();
client = new OkHttpClient();
new GetLocation(MyLocationService.this).execute();
return START_STICKY;
}
您很可能会看到与电源管理和警报的交互。以API 19 开头的所有警报默认情况下都是不精确,因此它们将与其他警报进行整理。此外,一旦设备进入低功耗状态,就会在 BroadcastReceiver
秒内发送警报,并且只要接收器正在执行其 onReceive()
方法,设备就会保证保持清醒。一旦它 returns 从该方法(以及与警报相关的任何其他 BroadcastReceiver
运行),设备将立即再次进入低功耗状态。由于您的应用程序之前已被终止,因此 Service
不再是 运行 并且不会获得 CPU 时间。
解决此问题的方法是使用 WakefulReceiver
,它在运行 onReceive()
时使用唤醒锁,启动您的 Service
进行处理。 Service
将在完成处理后释放唤醒锁。这篇文章会给你一个很好的解释:http://po.st/7UpipA
请注意,每分钟醒来一次会严重降低设备的电池寿命,因此您应该考虑取消此设置。