mirror of
https://github.com/AntennaPod/AntennaPod.git
synced 2026-08-18 02:53:10 +00:00
Fix possible memory leaks in new playback service (#8578)
### Description Fix possible memory leaks in new playback service ### Checklist <!-- To help us keep the issue tracker clean and work as efficient as possible, please make sure that you have done all of the following. You can tick the boxes below by placing an x inside the brackets like this: [x] --> - [x] I have read the contribution guidelines: https://github.com/AntennaPod/AntennaPod/blob/develop/CONTRIBUTING.md#submit-a-pull-request - [x] I have performed a self-review of my code, going through my changes line by line and carefully considering why this line change is necessary - [x] I have run the automated code checks using `./gradlew checkstyle lint` - [x] My code follows the style guidelines of the AntennaPod project: https://antennapod.org/contribute/develop/app/code-style - [x] I have mentioned the corresponding issue and the relevant keyword (e.g., "Closes: #xy") in the description (see https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) - [x] If it is a core feature, I have added automated tests
This commit is contained in:
committed by
GitHub
parent
bdfd540c32
commit
78af5e353b
@ -521,12 +521,16 @@ public abstract class PlaybackController {
|
||||
ListenableFuture<MediaController> controllerFuture =
|
||||
new MediaController.Builder(context, sessionToken).buildAsync();
|
||||
controllerFuture.addListener(() -> {
|
||||
MediaController controller = null;
|
||||
try {
|
||||
MediaController controller = controllerFuture.get();
|
||||
controller = controllerFuture.get();
|
||||
consumer.accept(controller);
|
||||
controller.release();
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (controller != null) {
|
||||
controller.release();
|
||||
}
|
||||
}
|
||||
}, MoreExecutors.directExecutor());
|
||||
|
||||
|
||||
@ -41,7 +41,6 @@ import de.danoeh.antennapod.storage.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.event.playback.SleepTimerUpdatedEvent;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import io.reactivex.rxjava3.core.Single;
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
|
||||
import java.util.Collections;
|
||||
@ -102,7 +101,6 @@ public class MediaLibrarySessionCallback implements MediaLibraryService.MediaLib
|
||||
}
|
||||
|
||||
private final Context context;
|
||||
private final CompositeDisposable disposables = new CompositeDisposable();
|
||||
|
||||
public MediaLibrarySessionCallback(Context context) {
|
||||
this.context = context;
|
||||
@ -264,7 +262,7 @@ public class MediaLibrarySessionCallback implements MediaLibraryService.MediaLib
|
||||
mediaItems, index, startPositionMs));
|
||||
}
|
||||
SettableFuture<MediaSession.MediaItemsWithStartPosition> future = SettableFuture.create();
|
||||
disposables.add(Single.fromCallable(
|
||||
Single.fromCallable(
|
||||
() -> {
|
||||
List<MediaItem> updatedItems = onAddMediaItems(mediaSession, controller, mediaItems).get();
|
||||
long mediaId = Long.parseLong(updatedItems.get(index).mediaId);
|
||||
@ -280,7 +278,7 @@ public class MediaLibrarySessionCallback implements MediaLibraryService.MediaLib
|
||||
}, error -> {
|
||||
Log.e(TAG, "Failed to load media", error);
|
||||
future.set(new MediaSession.MediaItemsWithStartPosition(mediaItems, index, startPositionMs));
|
||||
}));
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
@ -294,7 +292,7 @@ public class MediaLibrarySessionCallback implements MediaLibraryService.MediaLib
|
||||
}
|
||||
|
||||
SettableFuture<List<MediaItem>> future = SettableFuture.create();
|
||||
disposables.add(Single.fromCallable(() -> enrichMediaItems(mediaItems))
|
||||
Single.fromCallable(() -> enrichMediaItems(mediaItems))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(
|
||||
items -> future.set(items.isEmpty() ? Collections.emptyList() : items),
|
||||
@ -302,7 +300,7 @@ public class MediaLibrarySessionCallback implements MediaLibraryService.MediaLib
|
||||
Log.e(TAG, "Failed to load media items", error);
|
||||
future.set(Collections.emptyList());
|
||||
}
|
||||
));
|
||||
);
|
||||
return future;
|
||||
}
|
||||
|
||||
@ -312,7 +310,7 @@ public class MediaLibrarySessionCallback implements MediaLibraryService.MediaLib
|
||||
public ListenableFuture<MediaSession.MediaItemsWithStartPosition> onPlaybackResumption(
|
||||
@NonNull MediaSession mediaSession, @NonNull MediaSession.ControllerInfo controller) {
|
||||
SettableFuture<MediaSession.MediaItemsWithStartPosition> future = SettableFuture.create();
|
||||
disposables.add(Single.fromCallable(() -> {
|
||||
Single.fromCallable(() -> {
|
||||
FeedMedia media = DBReader.getFeedMedia(PlaybackPreferences.getCurrentlyPlayingFeedMediaId());
|
||||
// If there is no media to resume, media3 crashes. So instead of crashing, just play something random.
|
||||
if (media == null) {
|
||||
@ -343,7 +341,7 @@ public class MediaLibrarySessionCallback implements MediaLibraryService.MediaLib
|
||||
future.set(result);
|
||||
},
|
||||
future::setException
|
||||
));
|
||||
);
|
||||
return future;
|
||||
}
|
||||
|
||||
@ -373,10 +371,10 @@ public class MediaLibrarySessionCallback implements MediaLibraryService.MediaLib
|
||||
@NonNull MediaSession.ControllerInfo browser, @NonNull String mediaId) {
|
||||
if (BROWSABLE_MEDIA_IDS.contains(mediaId) || mediaId.startsWith(MediaItemAdapter.MEDIA_ID_FEED_PREFIX)) {
|
||||
SettableFuture<LibraryResult<MediaItem>> future = SettableFuture.create();
|
||||
disposables.add(Single.fromCallable(() -> createBrowsableMediaItem(mediaId))
|
||||
Single.fromCallable(() -> createBrowsableMediaItem(mediaId))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(item -> future.set(LibraryResult.ofItem(item, null)),
|
||||
future::setException));
|
||||
future::setException);
|
||||
return future;
|
||||
}
|
||||
return MediaLibraryService.MediaLibrarySession.Callback.super.onGetItem(session, browser, mediaId);
|
||||
@ -393,7 +391,7 @@ public class MediaLibrarySessionCallback implements MediaLibraryService.MediaLib
|
||||
|
||||
switch (parentId) {
|
||||
case MEDIA_ID_ROOT:
|
||||
disposables.add(Single.fromCallable(() -> ImmutableList.of(
|
||||
Single.fromCallable(() -> ImmutableList.of(
|
||||
createBrowsableMediaItem(MEDIA_ID_CONTINUE_LISTENING),
|
||||
createBrowsableMediaItem(MEDIA_ID_QUEUE),
|
||||
createBrowsableMediaItem(MEDIA_ID_DOWNLOADS),
|
||||
@ -401,10 +399,10 @@ public class MediaLibrarySessionCallback implements MediaLibraryService.MediaLib
|
||||
createBrowsableMediaItem(MEDIA_ID_SUBSCRIPTIONS)))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(items -> future.set(LibraryResult.ofItemList(items, params)),
|
||||
future::setException));
|
||||
future::setException);
|
||||
return future;
|
||||
case MEDIA_ID_SUBSCRIPTIONS:
|
||||
disposables.add(Single.fromCallable(DBReader::getFeedList)
|
||||
Single.fromCallable(DBReader::getFeedList)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(
|
||||
items -> {
|
||||
@ -416,10 +414,10 @@ public class MediaLibrarySessionCallback implements MediaLibraryService.MediaLib
|
||||
}
|
||||
future.set(LibraryResult.ofItemList(builder.build(), params));
|
||||
},
|
||||
future::setException));
|
||||
future::setException);
|
||||
return future;
|
||||
case MEDIA_ID_CONTINUE_LISTENING:
|
||||
disposables.add(Single.fromCallable(
|
||||
Single.fromCallable(
|
||||
() -> DBReader.getPausedQueue(CONTINUE_LISTENING_NUM_EPISODES))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(
|
||||
@ -429,10 +427,10 @@ public class MediaLibrarySessionCallback implements MediaLibraryService.MediaLib
|
||||
Log.e(TAG, "Failed to load continue listening", error);
|
||||
future.set(LibraryResult.ofItemList(ImmutableList.of(), params));
|
||||
}
|
||||
));
|
||||
);
|
||||
return future;
|
||||
default: // Episodes lists
|
||||
disposables.add(Single.fromCallable(() -> {
|
||||
Single.fromCallable(() -> {
|
||||
if (parentId.startsWith(MediaItemAdapter.MEDIA_ID_FEED_PREFIX)) {
|
||||
long feedId = Long.parseLong(parentId.split(":")[1]);
|
||||
return DBReader.getFeed(feedId, true, page * pageSize, pageSize).getItems();
|
||||
@ -451,7 +449,7 @@ public class MediaLibrarySessionCallback implements MediaLibraryService.MediaLib
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(items -> future.set(LibraryResult.ofItemList(
|
||||
MediaItemAdapter.fromItemList(context, items), params)),
|
||||
future::setException));
|
||||
future::setException);
|
||||
return future;
|
||||
}
|
||||
}
|
||||
@ -462,12 +460,12 @@ public class MediaLibrarySessionCallback implements MediaLibraryService.MediaLib
|
||||
@NonNull MediaLibraryService.MediaLibrarySession session, @NonNull MediaSession.ControllerInfo browser,
|
||||
@NonNull String query, int page, int pageSize, @Nullable MediaLibraryService.LibraryParams params) {
|
||||
SettableFuture<LibraryResult<ImmutableList<MediaItem>>> future = SettableFuture.create();
|
||||
disposables.add(Single.fromCallable(() ->
|
||||
Single.fromCallable(() ->
|
||||
DBReader.searchFeedItems(0, query, FeedItemFilter.unfiltered()))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(items -> future.set(LibraryResult.ofItemList(
|
||||
MediaItemAdapter.fromItemList(context, items), params)),
|
||||
future::setException));
|
||||
future::setException);
|
||||
return future;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user