diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java b/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java index daff651fdd..7bc83b6729 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/ExtractorSampleSource.java @@ -111,8 +111,8 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu private final EventListener eventListener; private final DataSource dataSource; private final ConditionVariable loadCondition; - private final Loader loader; private final ExtractorHolder extractorHolder; + private final Loader loader; private Callback callback; private Allocator allocator; @@ -171,8 +171,8 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu this.eventHandler = eventHandler; dataSource = dataSourceFactory.createDataSource(bandwidthMeter); loadCondition = new ConditionVariable(); - loader = new Loader("Loader:ExtractorSampleSource"); extractorHolder = new ExtractorHolder(extractorsFactory.createExtractors(), this); + loader = new Loader("Loader:ExtractorSampleSource", extractorHolder); pendingResetPositionUs = C.UNSET_TIME_US; sampleQueues = new DefaultTrackOutput[0]; length = C.LENGTH_UNBOUNDED; @@ -640,7 +640,7 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu /** * Stores a list of extractors and a selected extractor when the format has been detected. */ - private static final class ExtractorHolder { + private static final class ExtractorHolder implements Loader.Releasable { private final Extractor[] extractors; private final ExtractorOutput extractorOutput; @@ -691,6 +691,14 @@ public final class ExtractorSampleSource implements SampleSource, ExtractorOutpu return extractor; } + @Override + public void release() { + if (extractor != null) { + extractor.release(); + extractor = null; + } + } + } } diff --git a/library/src/main/java/com/google/android/exoplayer/upstream/Loader.java b/library/src/main/java/com/google/android/exoplayer/upstream/Loader.java index f7526ea785..ffef017e49 100644 --- a/library/src/main/java/com/google/android/exoplayer/upstream/Loader.java +++ b/library/src/main/java/com/google/android/exoplayer/upstream/Loader.java @@ -72,6 +72,18 @@ public final class Loader { } + /** + * An object that can be released on the loading thread when {@link Loader#release()} is called. + */ + public interface Releasable { + + /** + * Releases any resources associated with the instance. + */ + void release(); + + } + /** * A callback to be notified of {@link Loader} events. */ @@ -135,6 +147,7 @@ public final class Loader { private static final int MSG_FATAL_ERROR = 4; private final ExecutorService downloadExecutorService; + private final Releasable releasable; private LoadTask currentTask; private IOException fatalError; @@ -143,7 +156,17 @@ public final class Loader { * @param threadName A name for the loader's thread. */ public Loader(String threadName) { + this(threadName, null); + } + + /** + * @param threadName A name for the loader's thread. + * @param releasable An object to release on the loader's thread when {@link Loader#release()} is + * called. + */ + public Loader(String threadName, Releasable releasable) { this.downloadExecutorService = Util.newSingleThreadExecutor(threadName); + this.releasable = releasable; } /** @@ -223,6 +246,14 @@ public final class Loader { if (currentTask != null) { currentTask.cancel(true); } + if (releasable != null) { + downloadExecutorService.submit(new Runnable() { + @Override + public void run() { + releasable.release(); + } + }); + } downloadExecutorService.shutdown(); }