/** * Sets a {@link CachingCounters} to contain the number of bytes already downloaded and the * length for the content defined by a {@code dataSpec}. {@link CachingCounters#newlyCachedBytes} * is reset to 0. * * @param dataSpec Defines the data to be checked. * @param cache A {@link Cache} which has the data. * @param counters The {@link CachingCounters} to update. */ public static void getCached(DataSpec dataSpec, Cache cache, CachingCounters counters) { String key = getKey(dataSpec); long start = dataSpec.absoluteStreamPosition; long left = dataSpec.length != C.LENGTH_UNSET ? dataSpec.length : cache.getContentLength(key); counters.contentLength = left; counters.alreadyCachedBytes = 0; counters.newlyCachedBytes = 0; while (left != 0) { long blockLength = cache.getCachedBytes(key, start, left != C.LENGTH_UNSET ? left : Long.MAX_VALUE); if (blockLength > 0) { counters.alreadyCachedBytes += blockLength; } else { blockLength = -blockLength; if (blockLength == Long.MAX_VALUE) { return; } } start += blockLength; left -= left == C.LENGTH_UNSET ? 0 : blockLength; } }
private void configureExoMedia() { // Registers the media sources to use the OkHttp client instead of the standard Apache one // Note: the OkHttpDataSourceFactory can be found in the ExoPlayer extension library `extension-okhttp` ExoMedia.setDataSourceFactoryProvider(new ExoMedia.DataSourceFactoryProvider() { @NonNull @Override public DataSource.Factory provide(@NonNull String userAgent, @Nullable TransferListener<? super DataSource> listener) { // Updates the network data source to use the OKHttp implementation DataSource.Factory upstreamFactory = new OkHttpDataSourceFactory(new OkHttpClient(), userAgent, listener); // Adds a cache around the upstreamFactory Cache cache = new SimpleCache(getCacheDir(), new LeastRecentlyUsedCacheEvictor(50 * 1024 * 1024)); return new CacheDataSourceFactory(cache, upstreamFactory, CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR); } }); }
/** Asserts that the cache contains the given data for {@code uriString}. */ public static void assertDataCached(Cache cache, Uri uri, byte[] expected) throws IOException { CacheDataSource dataSource = new CacheDataSource(cache, DummyDataSource.INSTANCE, 0); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, new DataSpec(uri, DataSpec.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH)); try { inputStream.open(); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } } catch (IOException e) { // Ignore } finally { inputStream.close(); } MoreAsserts.assertEquals("Cached data doesn't match expected for '" + uri + "',", expected, outputStream.toByteArray()); }
/** * 删除所有的数据 {@code cache} pointed by the {@code key}. * * @param cache cache cache * @param key key 缓存文件 key */ public static void remove(Cache cache, String key) { NavigableSet<CacheSpan> cachedSpans = cache.getCachedSpans(key); if (cachedSpans == null) { return; } for (CacheSpan cachedSpan : cachedSpans) { try { cache.removeSpan(cachedSpan); } catch (Cache.CacheException e) { // do nothing } } }
@Override public void onCreate() { super.onCreate(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_DEFAULT_CHANNEL_ID, getString(R.string.notification_channel_name), NotificationManagerCompat.IMPORTANCE_DEFAULT); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.createNotificationChannel(notificationChannel); AudioAttributes audioAttributes = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_MEDIA) .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .build(); audioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN) .setOnAudioFocusChangeListener(audioFocusChangeListener) .setAcceptsDelayedFocusGain(false) .setWillPauseWhenDucked(true) .setAudioAttributes(audioAttributes) .build(); } audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); mediaSession = new MediaSessionCompat(this, "PlayerService"); mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); mediaSession.setCallback(mediaSessionCallback); Context appContext = getApplicationContext(); Intent activityIntent = new Intent(appContext, MainActivity.class); mediaSession.setSessionActivity(PendingIntent.getActivity(appContext, 0, activityIntent, 0)); Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null, appContext, MediaButtonReceiver.class); mediaSession.setMediaButtonReceiver(PendingIntent.getBroadcast(appContext, 0, mediaButtonIntent, 0)); exoPlayer = ExoPlayerFactory.newSimpleInstance(new DefaultRenderersFactory(this), new DefaultTrackSelector(), new DefaultLoadControl()); exoPlayer.addListener(exoPlayerListener); DataSource.Factory httpDataSourceFactory = new OkHttpDataSourceFactory(new OkHttpClient(), Util.getUserAgent(this, getString(R.string.app_name)), null); Cache cache = new SimpleCache(new File(this.getCacheDir().getAbsolutePath() + "/exoplayer"), new LeastRecentlyUsedCacheEvictor(1024 * 1024 * 100)); // 100 Mb max this.dataSourceFactory = new CacheDataSourceFactory(cache, httpDataSourceFactory, CacheDataSource.FLAG_BLOCK_ON_CACHE | CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR); this.extractorsFactory = new DefaultExtractorsFactory(); }
/** Asserts that the cache content is equal to the data in the {@code fakeDataSet}. */ public static void assertCachedData(Cache cache, FakeDataSet fakeDataSet) throws IOException { ArrayList<FakeData> allData = fakeDataSet.getAllData(); Uri[] uris = new Uri[allData.size()]; for (int i = 0; i < allData.size(); i++) { uris[i] = allData.get(i).uri; } assertCachedData(cache, fakeDataSet, uris); }
/** * Asserts that the cache content is equal to the given subset of data in the {@code fakeDataSet}. */ public static void assertCachedData(Cache cache, FakeDataSet fakeDataSet, String... uriStrings) throws IOException { Uri[] uris = new Uri[uriStrings.length]; for (int i = 0; i < uriStrings.length; i++) { uris[i] = Uri.parse(uriStrings[i]); } assertCachedData(cache, fakeDataSet, uris); }
/** * Asserts that the cache content is equal to the given subset of data in the {@code fakeDataSet}. */ public static void assertCachedData(Cache cache, FakeDataSet fakeDataSet, Uri... uris) throws IOException { int totalLength = 0; for (Uri uri : uris) { byte[] data = fakeDataSet.getData(uri).getData(); assertDataCached(cache, uri, data); totalLength += data.length; } assertEquals(totalLength, cache.getCacheSpace()); }
/** Asserts that the cache contains the given subset of data in the {@code fakeDataSet}. */ public static void assertDataCached(Cache cache, FakeDataSet fakeDataSet, Uri... uris) throws IOException { for (Uri uri : uris) { assertDataCached(cache, uri, fakeDataSet.getData(uri).getData()); } }
/** Asserts that there is no cache content for the given {@code uriStrings}. */ public static void assertDataNotCached(Cache cache, String... uriStrings) { for (String uriString : uriStrings) { Assert.assertNull("There is cached data for '" + uriString + "',", cache.getCachedSpans(CacheUtil.generateKey(Uri.parse(uriString)))); } }
/** * @param cache Cache instance to be used to store downloaded data. * @param upstreamDataSourceFactory A {@link Factory} for downloading data. * @param cacheReadDataSourceFactory A {@link Factory} for reading data from the cache. * If null, null is passed to {@link Downloader} constructor. * @param cacheWriteDataSinkFactory A {@link DataSink.Factory} for writing data to the cache. If * null, null is passed to {@link Downloader} constructor. * @param priorityTaskManager If one is given then the download priority is set lower than * loading. If null, null is passed to {@link Downloader} constructor. */ public DownloaderConstructorHelper(Cache cache, Factory upstreamDataSourceFactory, @Nullable Factory cacheReadDataSourceFactory, @Nullable DataSink.Factory cacheWriteDataSinkFactory, @Nullable PriorityTaskManager priorityTaskManager) { Assertions.checkNotNull(upstreamDataSourceFactory); this.cache = cache; this.upstreamDataSourceFactory = upstreamDataSourceFactory; this.cacheReadDataSourceFactory = cacheReadDataSourceFactory; this.cacheWriteDataSinkFactory = cacheWriteDataSinkFactory; this.priorityTaskManager = priorityTaskManager; }
/** Asserts that the cache is empty. */ public static void assertCacheEmpty(Cache cache) { assertEquals(0, cache.getCacheSpace()); }
/** Returns the {@link Cache} instance. */ public Cache getCache() { return cache; }
/** * Sets cache. * * @param cache 缓存文件实例 * @return Builder cache */ public Builder setCache(@NonNull Cache cache) { this.simpleCache = cache; return this; }
/** * @param cache Cache instance to be used to store downloaded data. * @param upstreamDataSourceFactory A {@link Factory} for downloading data. */ public DownloaderConstructorHelper(Cache cache, Factory upstreamDataSourceFactory) { this(cache, upstreamDataSourceFactory, null, null, null); }