/* * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ package com.facebook.imagepipeline.producers; import javax.annotation.concurrent.ThreadSafe; import javax.annotation.Nullable; import com.facebook.common.logging.FLog; /** * Base implementation of Consumer that implements error handling conforming to the * Consumer's contract. * * <p> This class also prevents execution of callbacks if one of final methods was called before: * onFinish(isLast = true), onFailure or onCancellation. * * <p> All callbacks are executed within a synchronized block, so that clients can act as if all * callbacks are called on single thread. * * @param <T> */ @ThreadSafe public abstract class BaseConsumer<T> implements Consumer<T> { /** * Set to true when onNewResult(isLast = true), onFailure or onCancellation is called. Further * calls to any of the 3 methods are not propagated */ private boolean mIsFinished; public BaseConsumer() { mIsFinished = false; } @Override public synchronized void onNewResult(@Nullable T newResult, boolean isLast) { if (mIsFinished) { return; } mIsFinished = isLast; try { onNewResultImpl(newResult, isLast); } catch (Exception e) { onUnhandledException(e); } } @Override public synchronized void onFailure(Throwable t) { if (mIsFinished) { return; } mIsFinished = true; try { onFailureImpl(t); } catch (Exception e) { onUnhandledException(e); } } @Override public synchronized void onCancellation() { if (mIsFinished) { return; } mIsFinished = true; try { onCancellationImpl(); } catch (Exception e) { onUnhandledException(e); } } /** * Called by onNewResult, override this method instead. */ protected abstract void onNewResultImpl(T newResult, boolean isLast); /** * Called by onFailure, override this method instead */ protected abstract void onFailureImpl(Throwable t); /** * Called by onCancellation, override this method instead */ protected abstract void onCancellationImpl(); /** * Called whenever onNewResultImpl or onFailureImpl throw an exception */ protected void onUnhandledException(Exception e) { FLog.wtf(this.getClass(), "unhandled exception", e); } }