/** 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; } }
@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(); }
/** * 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 void call(RelayObserver<T> t1) { NodeList.Node<Object> l; if (!state.terminated) { // ignore stale entries if still active l = state.replayObserverFromIndexTest(state.head(), t1, scheduler.now()); } else { // accept all if terminated l = state.replayObserverFromIndex(state.head(), t1); } t1.index(l); }
@Override public void evict(NodeList<Object> t1) { long now = scheduler.now(); while (!t1.isEmpty()) { NodeList.Node<Object> n = t1.head.next; if (test(n.value, now)) { t1.removeFirst(); } else { break; } } }
@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; }
@Override public void onNext(final T v) { Subscription previousSubscription = lastScheduledNotification.getAndSet( scheduler.schedule( new Action0() { @Override public void call() { observer.onNext(v); } }, timeout, unit)); // cancel previous if not already executed if (previousSubscription != null) { previousSubscription.unsubscribe(); } }
public Subscription onSubscribe(final Observer<? super T> observer) { final Iterator<? extends T> iterator = iterable.iterator(); return scheduler.schedule( new Action1<Action0>() { @Override public void call(Action0 self) { try { if (iterator.hasNext()) { T x = iterator.next(); observer.onNext(x); self.call(); } else { observer.onCompleted(); } } catch (Exception e) { observer.onError(e); } } }); }
@Override public void call(SingleSubscriber<? super T> singleSubscriber) { Worker worker = scheduler.createWorker(); singleSubscriber.add(worker); worker.schedule(new ScalarSynchronousSingleAction<T>(singleSubscriber, value)); }
@Override public Object call(Object t1) { return new Timestamped<Object>(scheduler.now(), t1); }