@Test public void onStop_calledOnMainThread() throws Exception { final SettableFuture<Looper> looperFuture = SettableFuture.create(); final JobService service = new JobService() { @Override public boolean onStartJob(@NonNull JobParameters job) { return true; } @Override public boolean onStopJob(@NonNull JobParameters job) { looperFuture.set(Looper.myLooper()); return false; } }; Job jobSpec = TestUtil.getBuilderWithNoopValidator() .setTag("tag") .setService(service.getClass()) .setTrigger(Trigger.NOW) .build(); final Bundle jobSpecData = getJobCoder().encode(jobSpec, new Bundle()); IRemoteJobService.Stub.asInterface(service.onBind(null)).start(jobSpecData, noopCallback); Executors.newSingleThreadExecutor() .submit( new Runnable() { @Override public void run() { try { IRemoteJobService.Stub.asInterface(service.onBind(null)).stop(jobSpecData, true); } catch (RemoteException e) { throw new AssertionError("calling stop on binder unexpectedly failed", e); } } }) .get(1, TimeUnit.SECONDS); flush(service); assertEquals( "onStopJob was not called on main thread", Looper.getMainLooper(), looperFuture.get(1, TimeUnit.SECONDS)); }
@Nullable @Override @MainThread public final IBinder onBind(Intent intent) { return binder; }
JobService extends Service { @Nullable @Override @MainThread public final IBinder onBind(Intent intent) { return binder; } }
JobService extends Service { @Nullable @Override @MainThread public final IBinder onBind(Intent intent) { return binder; }  }
JobService extends Service { @Nullable @Override @MainThread public final IBinder onBind(Intent intent) { return binder; }  @MainThread abstract boolean onStartJob(@NonNull JobParameters job); @MainThread abstract boolean onStopJob(@NonNull JobParameters job); @AnyThread final void jobFinished(@NonNull JobParameters job, boolean needsReschedule); @Override @MainThread final int onStartCommand(Intent intent, int flags, int startId); @Nullable @Override @MainThread final IBinder onBind(Intent intent); @Override @MainThread final boolean onUnbind(Intent intent); @Override @MainThread final void onRebind(Intent intent); @Override @MainThread final void onStart(Intent intent, int startId); @Override @MainThread final void onConfigurationChanged(Configuration newConfig); @Override @MainThread final void onTaskRemoved(Intent rootIntent); }
JobService extends Service { @Nullable @Override @MainThread public final IBinder onBind(Intent intent) { return binder; }  @MainThread abstract boolean onStartJob(@NonNull JobParameters job); @MainThread abstract boolean onStopJob(@NonNull JobParameters job); @AnyThread final void jobFinished(@NonNull JobParameters job, boolean needsReschedule); @Override @MainThread final int onStartCommand(Intent intent, int flags, int startId); @Nullable @Override @MainThread final IBinder onBind(Intent intent); @Override @MainThread final boolean onUnbind(Intent intent); @Override @MainThread final void onRebind(Intent intent); @Override @MainThread final void onStart(Intent intent, int startId); @Override @MainThread final void onConfigurationChanged(Configuration newConfig); @Override @MainThread final void onTaskRemoved(Intent rootIntent); static final int RESULT_SUCCESS; static final int RESULT_FAIL_RETRY; static final int RESULT_FAIL_NORETRY; }