/** Pulls bitmap from diskcache */ private @Nullable ParcelFileDescriptor createPipe(final ArtInfo artInfo) { final byte[] bytes = mL2Cache.getBytes(artInfo.cacheKey()); if (bytes == null) { return null; } try { final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); final OutputStream out = new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]); final ParcelFileDescriptor in = pipe[0]; final Scheduler.Worker worker = mScheduler.createWorker(); worker.schedule( new Action0() { @Override public void call() { try { IOUtils.write(bytes, out); out.flush(); } catch (IOException e) { Timber.w("createPipe(e=%s) for %s", e.getMessage(), artInfo); } finally { IOUtils.closeQuietly(out); worker.unsubscribe(); } } }); return in; } catch (IOException e) { Timber.e(e, "createPipe() for %s", artInfo); return null; } }
/** * Eagerly creates a pipe, then blocks on a background thread while we wait for the fetcher to * return the bitmap, simply closing the pipe if no art was found */ private @Nullable ParcelFileDescriptor createPipe2(final ArtInfo artInfo) { try { final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe(); final OutputStream out = new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]); final ParcelFileDescriptor in = pipe[0]; final Scheduler.Worker worker = mScheduler.createWorker(); worker.schedule( new Action0() { @Override public void call() { OptionalBitmap bitmap = null; ArtworkFetcherService.Connection binder = null; try { // make a new request and wait for it to come in. binder = ArtworkFetcherService.bindService(getContext()); final BlockingQueue<OptionalBitmap> queue = new LinkedBlockingQueue<>(1); final CompletionListener listener = new CompletionListener() { @Override public void onError(Throwable e) { Timber.w("onError(%s) for %s", e.getMessage(), artInfo); queue.offer(new OptionalBitmap(null)); } @Override public void onNext(Bitmap o) { queue.offer(new OptionalBitmap(o)); } }; if (!binder.getService().newRequest(artInfo, listener)) { throw new InterruptedException("Enqueue failed"); } bitmap = queue.take(); if (bitmap.hasBitmap()) { byte[] bytes = mL2Cache.bitmapToBytes(bitmap.getBitmap()); IOUtils.write(bytes, out); out.flush(); } } catch (InterruptedException | IOException e) { Timber.w("createPipe2(e=%s) for %s", e.getMessage(), artInfo); if (binder != null) { binder.getService().cancelRequest(artInfo); } } finally { if (bitmap != null) bitmap.recycle(); IOUtils.closeQuietly(binder); IOUtils.closeQuietly(out); worker.unsubscribe(); } } }); return in; } catch (IOException e) { Timber.e(e, "createPipe2() for %s", artInfo); return null; } }
@Override public Subscriber<? super T> call(final Subscriber<? super List<T>> child) { final Worker inner = scheduler.createWorker(); child.add(inner); if (timespan == timeshift) { ExactSubscriber bsub = new ExactSubscriber(new SerializedSubscriber<List<T>>(child), inner); bsub.scheduleExact(); return bsub; } InexactSubscriber bsub = new InexactSubscriber(new SerializedSubscriber<List<T>>(child), inner); bsub.startNewChunk(); bsub.scheduleChunk(); return bsub; }
@Test public void shouldScheduleDelayedActionOnHandlerThread() { Handler handler = mock(Handler.class); Action0 action = mock(Action0.class); Scheduler scheduler = AndroidSchedulers.from(handler); Worker inner = scheduler.createWorker(); inner.schedule(action, 1, SECONDS); // verify that we post to the given Handler ArgumentCaptor<Runnable> runnable = ArgumentCaptor.forClass(Runnable.class); verify(handler).postDelayed(runnable.capture(), eq(1000L)); // verify that the given handler delegates to our action runnable.getValue().run(); verify(action).call(); }
@Override public void call(SingleSubscriber<? super T> singleSubscriber) { Worker worker = scheduler.createWorker(); singleSubscriber.add(worker); worker.schedule(new ScalarSynchronousSingleAction<T>(singleSubscriber, value)); }