-Added serialized cache for transferring serializable objects too large for intent transactions.
-Fixed potential transaction too large exceptions for player intents.
This commit is contained in:
parent
b4668367c6
commit
a1220c77da
5 changed files with 141 additions and 23 deletions
|
|
@ -7,6 +7,8 @@ import android.content.Intent;
|
|||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
|
@ -33,9 +35,9 @@ import org.schabi.newpipe.fragments.list.feed.FeedFragment;
|
|||
import org.schabi.newpipe.fragments.list.kiosk.KioskFragment;
|
||||
import org.schabi.newpipe.fragments.list.playlist.PlaylistFragment;
|
||||
import org.schabi.newpipe.fragments.list.search.SearchFragment;
|
||||
import org.schabi.newpipe.fragments.local.bookmark.LastPlayedFragment;
|
||||
import org.schabi.newpipe.fragments.local.bookmark.LocalPlaylistFragment;
|
||||
import org.schabi.newpipe.fragments.local.bookmark.MostPlayedFragment;
|
||||
import org.schabi.newpipe.fragments.local.bookmark.LastPlayedFragment;
|
||||
import org.schabi.newpipe.history.HistoryActivity;
|
||||
import org.schabi.newpipe.player.BackgroundPlayer;
|
||||
import org.schabi.newpipe.player.BackgroundPlayerActivity;
|
||||
|
|
@ -59,39 +61,41 @@ public class NavigationHelper {
|
|||
// Players
|
||||
//////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
public static Intent getPlayerIntent(final Context context,
|
||||
final Class targetClazz,
|
||||
final PlayQueue playQueue,
|
||||
final String quality) {
|
||||
Intent intent = new Intent(context, targetClazz)
|
||||
.putExtra(VideoPlayer.PLAY_QUEUE, playQueue);
|
||||
public static Intent getPlayerIntent(@NonNull final Context context,
|
||||
@NonNull final Class targetClazz,
|
||||
@NonNull final PlayQueue playQueue,
|
||||
@Nullable final String quality) {
|
||||
Intent intent = new Intent(context, targetClazz);
|
||||
|
||||
final String cacheKey = SerializedCache.getInstance().put(playQueue, PlayQueue.class);
|
||||
if (cacheKey != null) intent.putExtra(VideoPlayer.PLAY_QUEUE_KEY, cacheKey);
|
||||
if (quality != null) intent.putExtra(VideoPlayer.PLAYBACK_QUALITY, quality);
|
||||
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static Intent getPlayerIntent(final Context context,
|
||||
final Class targetClazz,
|
||||
final PlayQueue playQueue) {
|
||||
public static Intent getPlayerIntent(@NonNull final Context context,
|
||||
@NonNull final Class targetClazz,
|
||||
@NonNull final PlayQueue playQueue) {
|
||||
return getPlayerIntent(context, targetClazz, playQueue, null);
|
||||
}
|
||||
|
||||
public static Intent getPlayerEnqueueIntent(final Context context,
|
||||
final Class targetClazz,
|
||||
final PlayQueue playQueue,
|
||||
public static Intent getPlayerEnqueueIntent(@NonNull final Context context,
|
||||
@NonNull final Class targetClazz,
|
||||
@NonNull final PlayQueue playQueue,
|
||||
final boolean selectOnAppend) {
|
||||
return getPlayerIntent(context, targetClazz, playQueue)
|
||||
.putExtra(BasePlayer.APPEND_ONLY, true)
|
||||
.putExtra(BasePlayer.SELECT_ON_APPEND, selectOnAppend);
|
||||
}
|
||||
|
||||
public static Intent getPlayerIntent(final Context context,
|
||||
final Class targetClazz,
|
||||
final PlayQueue playQueue,
|
||||
public static Intent getPlayerIntent(@NonNull final Context context,
|
||||
@NonNull final Class targetClazz,
|
||||
@NonNull final PlayQueue playQueue,
|
||||
final int repeatMode,
|
||||
final float playbackSpeed,
|
||||
final float playbackPitch,
|
||||
final String playbackQuality) {
|
||||
@Nullable final String playbackQuality) {
|
||||
return getPlayerIntent(context, targetClazz, playQueue, playbackQuality)
|
||||
.putExtra(BasePlayer.REPEAT_MODE, repeatMode)
|
||||
.putExtra(BasePlayer.PLAYBACK_SPEED, playbackSpeed)
|
||||
|
|
|
|||
112
app/src/main/java/org/schabi/newpipe/util/SerializedCache.java
Normal file
112
app/src/main/java/org/schabi/newpipe/util/SerializedCache.java
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
package org.schabi.newpipe.util;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.util.LruCache;
|
||||
import android.util.Log;
|
||||
|
||||
import org.schabi.newpipe.MainActivity;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SerializedCache {
|
||||
private static final boolean DEBUG = MainActivity.DEBUG;
|
||||
private final String TAG = getClass().getSimpleName();
|
||||
|
||||
private static final SerializedCache instance = new SerializedCache();
|
||||
private static final int MAX_ITEMS_ON_CACHE = 5;
|
||||
|
||||
private static final LruCache<String, CacheData> lruCache =
|
||||
new LruCache<>(MAX_ITEMS_ON_CACHE);
|
||||
|
||||
private SerializedCache() {
|
||||
//no instance
|
||||
}
|
||||
|
||||
public static SerializedCache getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T> T take(@NonNull final String key, @NonNull final Class<T> type) {
|
||||
if (DEBUG) Log.d(TAG, "take() called with: key = [" + key + "]");
|
||||
synchronized (lruCache) {
|
||||
return lruCache.get(key) != null ? getItem(lruCache.remove(key), type) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T> T get(@NonNull final String key, @NonNull final Class<T> type) {
|
||||
if (DEBUG) Log.d(TAG, "get() called with: key = [" + key + "]");
|
||||
synchronized (lruCache) {
|
||||
final CacheData data = lruCache.get(key);
|
||||
return data != null ? getItem(data, type) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T extends Serializable> String put(@NonNull T item, @NonNull final Class<T> type) {
|
||||
final String key = UUID.randomUUID().toString();
|
||||
return put(key, item, type) ? key : null;
|
||||
}
|
||||
|
||||
public <T extends Serializable> boolean put(@NonNull final String key, @NonNull T item,
|
||||
@NonNull final Class<T> type) {
|
||||
if (DEBUG) Log.d(TAG, "put() called with: key = [" + key + "], item = [" + item + "]");
|
||||
synchronized (lruCache) {
|
||||
try {
|
||||
lruCache.put(key, new CacheData<>(clone(item, type), type));
|
||||
return true;
|
||||
} catch (final Exception error) {
|
||||
Log.e(TAG, "Serialization failed for: ", error);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
if (DEBUG) Log.d(TAG, "clear() called");
|
||||
synchronized (lruCache) {
|
||||
lruCache.evictAll();
|
||||
}
|
||||
}
|
||||
|
||||
public long size() {
|
||||
synchronized (lruCache) {
|
||||
return lruCache.size();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private <T> T getItem(@NonNull final CacheData data, @NonNull final Class<T> type) {
|
||||
return type.isAssignableFrom(data.type) ? type.cast(data.item) : null;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private <T extends Serializable> T clone(@NonNull T item,
|
||||
@NonNull final Class<T> type) throws Exception {
|
||||
final ByteArrayOutputStream bytesOutput = new ByteArrayOutputStream();
|
||||
try (final ObjectOutputStream objectOutput = new ObjectOutputStream(bytesOutput)) {
|
||||
objectOutput.writeObject(item);
|
||||
objectOutput.flush();
|
||||
}
|
||||
final Object clone = new ObjectInputStream(
|
||||
new ByteArrayInputStream(bytesOutput.toByteArray())).readObject();
|
||||
return type.cast(clone);
|
||||
}
|
||||
|
||||
final private static class CacheData<T> {
|
||||
private final T item;
|
||||
private final Class<T> type;
|
||||
|
||||
private CacheData(@NonNull final T item, @NonNull Class<T> type) {
|
||||
this.item = item;
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue