Android Service
Кирилл Розов
Service - это компонент приложения,
который может выполнять длительные
операции в фоне, и не предоставляет
графического интерфейса для
взаимодействия с пользователем
Задачи для решения с
помощью Service
• Сетевые операции
• Взаимодействие с сервером
• Загрузка файлов
• Управление медиаплеером: музыка, подкасты,
Chromecast
• I/O операции
• Взаимодействие с Content Provider
Основные типы сервисов
• Started Service
• Foreground Service
• Bounded Service
• JobScheduler (API 21+) или GcmNetworkManager
(API 9+)
Started Service
Жизненный цикл
• onCreate()
• onStartCommand(Intent intent, int flags, int startId)
• onDestroy()
Пример
public class SampleService extends Service {

Handler mHandler;



@Override

public void onCreate() {

super.onCreate();

mHandler = new Handler();

}



@Override

public void onDestroy() {

super.onDestroy();

mHandler = null;

}

}
Пример
public class SampleService extends Service {

…



@Override

public int onStartCommand(@Nullable Intent intent,
int flags,
int startId) {

mHandler.postDelayed(() -> stopSelf(startId), showToast());

return START_STICKY;

}

…
}
onStartCommand()
• START_NOT_STICKY

Не пересоздает Service
• START_STICKY

Пересоздает Service, но не доставляет последний Intent
• START_REDELIVER_INTENT

Пересоздает Service и доставляет последний Intent
IntentService
public class HelloIntentService extends IntentService {
  public HelloIntentService() {
      super("HelloIntentService");
  }
  @Override
  protected void onHandleIntent(Intent intent) {
      try {
          Thread.sleep(5000);
      } catch (InterruptedException e) {
          Thread.currentThread().interrupt();
      }
  }
}
Важно
• Service не создает отдельных потоков или
процессов
• Используйте WakeLock
• Не забывайте останавливать Service
• Останавливайте Service методом stopSelfResult(int
startId), вместо stopSelf()
• Добавляйте описание вашему Service в Android
Manifest
Bounded Service
Жизненный цикл
• onCreate()
• onBind(Intent intent)
• onRebind(Intent intent)
• onUnbind(Intent intent)
• onDestroy()
Реализация IBinder
• Локальное использование
• … extends Binder
• Межпроцессное взаимодействие
• Messenger
• AIDL
Пример
public class LocalService extends Service {
    private final IBinder mBinder = new LocalBinder();
    public class LocalBinder extends Binder {
        LocalService getService() {
            return LocalService.this;
        }
    }
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
…
}
public class BindingActivity extends Activity {
    LocalService mService;
    boolean mBound = false;
    private final ServiceConnection mConnection = new LocalServiceConnection();
    @Override
    protected void onStart() {
        super.onStart();
        bindService(new Intent(this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE);
    }
    @Override
    protected void onStop() {
        super.onStop();
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }
    private final class LocalServiceConnection implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            mBound = true;
        }
        @Override
        public void onServiceDisconnected(ComponentName service) {
            mBound = false;
        }
    };
}
Важно
• Делать unbindService() для каждого bindService()
• Используйте только явные Intent в bindService()
• Binding с Service можно выполнить только из
Activity, Serivce и Content Provider
Жизненный цикл
Foreground Service
public class SampleForegroundService extends Service {

@Override

public void onCreate() {

super.onCreate();

NotificationCompat.Builder builder = new NotificationCompat.Builder(this)

.setContentTitle("Sample foreground service")

.setContentTitle("Progress running")

.setProgress(0, 1, true)

.setSmallIcon(R.mipmap.ic_noficiation);

Notification notification = builder.build();

startForeground(FOREGROUND_NOTIFICATION_ID, notification);

}
…

}
Job Scheduler
Возможности JobScheduler
• Отложенный запуск задач на основе заданных
критериев
• Периодическое выполнение
• Работы в Doze Mode
• Группировка запуска задач
• Замена CONNECTIVITY_ACTION broadcast,
регистрируемый через AndroidManifest
Пример
ComponentName jobServiceComponent =
new ComponentName(this, JobSchedulerService.class);
JobInfo.Builder builder =

new JobInfo.Builder(SAMPLE_JOB_ID, jobServiceComponent)

.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)

.setPersisted(false)

.setRequiresDeviceIdle(false)

.setRequiresCharging(false)

.setOverrideDeadline(1_000);
Пример
JobScheduler jobScheduler = (JobScheduler)
getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(builder.build());
Пример
public class JobSchedulerService extends JobService {



public static final int SAMPLE_JOB_ID = 1000;



@Override

public boolean onStartJob(JobParameters params) {
if (params.getJobId() == Constants.SAMPLE_JOB_ID) {

Handler handler = new Handler();

handler.postDelayed(() -> jobFinished(params, false), duration);

}
return false;
}
@Override
public boolean onStopJob(JobParameters params) {

return false;
}
}
AndroidManifest.xml
<service

android:name=“.JobSchedulerService"
android:exported=“true”

android:permission="android.permission.BIND_JOB_SERVICE"

/>
Условия JobScheduler
• Зарядка
• Тип сети
• NETWORK_TYPE_NONE (по умолчанию)
• NETWORK_TYPE_ANY
• NETWORK_TYPE_NOT_ROAMING (API 24+)
• NETWORK_TYPE_UNMETERED
• Устройство находится в простое
GcmNetworkManager
Пример
public class TaskSampleService extends GcmTaskService {



@GcmTaskResultDef

@Override

public int onRunTask(TaskParams taskParams) {

if (SAMPLE_JOB_TAG.equals(taskParams.getTag())) {

// Do long work. Execute on background thread by default.

}

return GcmNetworkManager.RESULT_SUCCESS;

}

}
AndroidManifest.xml
<service
android:name=“.TaskSampleService"
     android:exported="true"
     android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE">
         <intent-filter>
              <action android:name="com.google.android.gms.gcm.ACTION_TASK_READY"/>
         </intent-filter>
</service>
Пример
public class GcmNetworkManagerService extends GcmTaskService {



@Override

public void onInitializeTasks() {

// Restore tasks after application package updated.
// Not called on first start.
}

}
Пример
OneoffTask.Builder builder = new OneoffTask.Builder();

builder.setService(GcmTaskService.class)

.setRequiredNetwork(Task.NETWORK_STATE_ANY)

.setPersisted(true)

.setRequiresCharging(false)

.setExecutionWindow(0, TimeUnit.SECONDS.toMillis(1));

OneoffTask task = builder.build();



GcmNetworkManager.getInstance(this) .schedule(task);
Условия
GcmNetworkManager
• Зарядка
• Тип сети
• NETWORK_STATE_ANY
• NETWORK_STATE_CONNECTED
• NETWORK_STATE_UNMETERED
Отличия JobScheduler и
GcmNetworkManager
• Для работы GcmNetworkManager обязательно необходимо
наличие Google Play Service на устройстве в рабочем состояние
• GcmNetworkManager захватывает блокировку
PowerManager.WakeLock для вашего Service, и ваша задача
имеет 3 минуты на выполнение. В противном случае WakeLock
будет снят и перезапуск задачи не будет иметь эффекта.
• При обновление или удаление вашего приложения
GcmNetworkManager может сбрасывает всю очередь тасков и
её нужно восстанавливать
• Для повторяющихся задач в GcmNetworkManager используется
отдельный класс - PeriodicTask
Полезные сервисы
• DownloadManager
• Android Upload Service (github.com/gotev/
android-upload-service)
Спасибо за внимание

Android service

  • 1.
  • 2.
    Service - этокомпонент приложения, который может выполнять длительные операции в фоне, и не предоставляет графического интерфейса для взаимодействия с пользователем
  • 3.
    Задачи для решенияс помощью Service • Сетевые операции • Взаимодействие с сервером • Загрузка файлов • Управление медиаплеером: музыка, подкасты, Chromecast • I/O операции • Взаимодействие с Content Provider
  • 4.
    Основные типы сервисов •Started Service • Foreground Service • Bounded Service • JobScheduler (API 21+) или GcmNetworkManager (API 9+)
  • 5.
  • 6.
    Жизненный цикл • onCreate() •onStartCommand(Intent intent, int flags, int startId) • onDestroy()
  • 7.
    Пример public class SampleServiceextends Service {
 Handler mHandler;
 
 @Override
 public void onCreate() {
 super.onCreate();
 mHandler = new Handler();
 }
 
 @Override
 public void onDestroy() {
 super.onDestroy();
 mHandler = null;
 }
 }
  • 8.
    Пример public class SampleServiceextends Service {
 …
 
 @Override
 public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
 mHandler.postDelayed(() -> stopSelf(startId), showToast());
 return START_STICKY;
 }
 … }
  • 9.
    onStartCommand() • START_NOT_STICKY
 Не пересоздаетService • START_STICKY
 Пересоздает Service, но не доставляет последний Intent • START_REDELIVER_INTENT
 Пересоздает Service и доставляет последний Intent
  • 10.
    IntentService public class HelloIntentServiceextends IntentService {   public HelloIntentService() {       super("HelloIntentService");   }   @Override   protected void onHandleIntent(Intent intent) {       try {           Thread.sleep(5000);       } catch (InterruptedException e) {           Thread.currentThread().interrupt();       }   } }
  • 11.
    Важно • Service несоздает отдельных потоков или процессов • Используйте WakeLock • Не забывайте останавливать Service • Останавливайте Service методом stopSelfResult(int startId), вместо stopSelf() • Добавляйте описание вашему Service в Android Manifest
  • 12.
  • 13.
    Жизненный цикл • onCreate() •onBind(Intent intent) • onRebind(Intent intent) • onUnbind(Intent intent) • onDestroy()
  • 15.
    Реализация IBinder • Локальноеиспользование • … extends Binder • Межпроцессное взаимодействие • Messenger • AIDL
  • 16.
    Пример public class LocalServiceextends Service {     private final IBinder mBinder = new LocalBinder();     public class LocalBinder extends Binder {         LocalService getService() {             return LocalService.this;         }     }     @Override     public IBinder onBind(Intent intent) {         return mBinder;     } … }
  • 17.
    public class BindingActivityextends Activity {     LocalService mService;     boolean mBound = false;     private final ServiceConnection mConnection = new LocalServiceConnection();     @Override     protected void onStart() {         super.onStart();         bindService(new Intent(this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE);     }     @Override     protected void onStop() {         super.onStop();         if (mBound) {             unbindService(mConnection);             mBound = false;         }     }     private final class LocalServiceConnection implements ServiceConnection {         @Override         public void onServiceConnected(ComponentName className, IBinder service) {             LocalBinder binder = (LocalBinder) service;             mService = binder.getService();             mBound = true;         }         @Override         public void onServiceDisconnected(ComponentName service) {             mBound = false;         }     }; }
  • 18.
    Важно • Делать unbindService()для каждого bindService() • Используйте только явные Intent в bindService() • Binding с Service можно выполнить только из Activity, Serivce и Content Provider
  • 19.
  • 20.
    Foreground Service public classSampleForegroundService extends Service {
 @Override
 public void onCreate() {
 super.onCreate();
 NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
 .setContentTitle("Sample foreground service")
 .setContentTitle("Progress running")
 .setProgress(0, 1, true)
 .setSmallIcon(R.mipmap.ic_noficiation);
 Notification notification = builder.build();
 startForeground(FOREGROUND_NOTIFICATION_ID, notification);
 } …
 }
  • 22.
  • 23.
    Возможности JobScheduler • Отложенныйзапуск задач на основе заданных критериев • Периодическое выполнение • Работы в Doze Mode • Группировка запуска задач • Замена CONNECTIVITY_ACTION broadcast, регистрируемый через AndroidManifest
  • 24.
    Пример ComponentName jobServiceComponent = newComponentName(this, JobSchedulerService.class); JobInfo.Builder builder =
 new JobInfo.Builder(SAMPLE_JOB_ID, jobServiceComponent)
 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
 .setPersisted(false)
 .setRequiresDeviceIdle(false)
 .setRequiresCharging(false)
 .setOverrideDeadline(1_000);
  • 25.
    Пример JobScheduler jobScheduler =(JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE); jobScheduler.schedule(builder.build());
  • 26.
    Пример public class JobSchedulerServiceextends JobService {
 
 public static final int SAMPLE_JOB_ID = 1000;
 
 @Override
 public boolean onStartJob(JobParameters params) { if (params.getJobId() == Constants.SAMPLE_JOB_ID) {
 Handler handler = new Handler();
 handler.postDelayed(() -> jobFinished(params, false), duration);
 } return false; } @Override public boolean onStopJob(JobParameters params) {
 return false; } }
  • 27.
  • 28.
    Условия JobScheduler • Зарядка •Тип сети • NETWORK_TYPE_NONE (по умолчанию) • NETWORK_TYPE_ANY • NETWORK_TYPE_NOT_ROAMING (API 24+) • NETWORK_TYPE_UNMETERED • Устройство находится в простое
  • 29.
  • 30.
    Пример public class TaskSampleServiceextends GcmTaskService {
 
 @GcmTaskResultDef
 @Override
 public int onRunTask(TaskParams taskParams) {
 if (SAMPLE_JOB_TAG.equals(taskParams.getTag())) {
 // Do long work. Execute on background thread by default.
 }
 return GcmNetworkManager.RESULT_SUCCESS;
 }
 }
  • 31.
    AndroidManifest.xml <service android:name=“.TaskSampleService"      android:exported="true"     android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE">          <intent-filter>               <action android:name="com.google.android.gms.gcm.ACTION_TASK_READY"/>          </intent-filter> </service>
  • 32.
    Пример public class GcmNetworkManagerServiceextends GcmTaskService {
 
 @Override
 public void onInitializeTasks() {
 // Restore tasks after application package updated. // Not called on first start. }
 }
  • 33.
    Пример OneoffTask.Builder builder =new OneoffTask.Builder();
 builder.setService(GcmTaskService.class)
 .setRequiredNetwork(Task.NETWORK_STATE_ANY)
 .setPersisted(true)
 .setRequiresCharging(false)
 .setExecutionWindow(0, TimeUnit.SECONDS.toMillis(1));
 OneoffTask task = builder.build();
 
 GcmNetworkManager.getInstance(this) .schedule(task);
  • 34.
    Условия GcmNetworkManager • Зарядка • Типсети • NETWORK_STATE_ANY • NETWORK_STATE_CONNECTED • NETWORK_STATE_UNMETERED
  • 35.
    Отличия JobScheduler и GcmNetworkManager •Для работы GcmNetworkManager обязательно необходимо наличие Google Play Service на устройстве в рабочем состояние • GcmNetworkManager захватывает блокировку PowerManager.WakeLock для вашего Service, и ваша задача имеет 3 минуты на выполнение. В противном случае WakeLock будет снят и перезапуск задачи не будет иметь эффекта. • При обновление или удаление вашего приложения GcmNetworkManager может сбрасывает всю очередь тасков и её нужно восстанавливать • Для повторяющихся задач в GcmNetworkManager используется отдельный класс - PeriodicTask
  • 36.
    Полезные сервисы • DownloadManager •Android Upload Service (github.com/gotev/ android-upload-service)
  • 37.