From 8f9715440bbed3854c96267bb2a56b41717f3cfd Mon Sep 17 00:00:00 2001 From: wp <517309507@qq.com> Date: Thu, 25 Nov 2021 12:37:36 +0800 Subject: [PATCH] 2.1.9 --- app/build.gradle | 2 +- .../imageviewer/demo/business/ViewerHelper.kt | 12 +- .../iielse/imageviewer/demo/data/Api.kt | 7 +- .../imageviewer/demo/data/repository.kt | 1 + build.gradle | 4 +- .../widgets/video/ExoSourceManager.java | 371 ------------------ .../imageviewer/widgets/video/ExoVideoView.kt | 8 - 7 files changed, 14 insertions(+), 391 deletions(-) delete mode 100644 imageviewer/src/main/java/com/github/iielse/imageviewer/widgets/video/ExoSourceManager.java diff --git a/app/build.gradle b/app/build.gradle index 1c6fc70..a36bd8d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -48,7 +48,7 @@ dependencies { implementation 'com.google.android.exoplayer:exoplayer:2.16.1' implementation project(':imageviewer') -// implementation 'com.github.iielse:imageviewer:2.1.8' +// implementation 'com.github.iielse:imageviewer:2.1.9' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'io.reactivex.rxjava2:rxjava:2.2.19' } diff --git a/app/src/main/java/com/github/iielse/imageviewer/demo/business/ViewerHelper.kt b/app/src/main/java/com/github/iielse/imageviewer/demo/business/ViewerHelper.kt index 547e740..41f97fa 100644 --- a/app/src/main/java/com/github/iielse/imageviewer/demo/business/ViewerHelper.kt +++ b/app/src/main/java/com/github/iielse/imageviewer/demo/business/ViewerHelper.kt @@ -41,18 +41,18 @@ object ViewerHelper { // viewer 构造的基本元素 val builder = ImageViewerBuilder( context = context, - initKey = clickedData.id, - dataProvider = myDataProvider(clickedData), - imageLoader = MyImageLoader(), - transformer = MyTransformer() + initKey = clickedData.id, // 被点击的图片id + dataProvider = myDataProvider(clickedData), // 数据提供者. 和调用者业务强绑定 + imageLoader = MyImageLoader(), // 自定义实现 + transformer = MyTransformer() // 固定写法. 实现 ViewerTransitionHelper 确定 进场退场动画 ) MyViewerCustomizer().process(context, builder) // 添加自定义业务逻辑和UI处理 - if (fullScreen) { + if (fullScreen) { // builder.setViewerFactory(object : ImageViewerDialogFragment.Factory() { override fun build() = FullScreenImageViewerDialogFragment() - }) + }) // 对弹窗增加自定义内容 } return builder } diff --git a/app/src/main/java/com/github/iielse/imageviewer/demo/data/Api.kt b/app/src/main/java/com/github/iielse/imageviewer/demo/data/Api.kt index c93a84a..cc53d2c 100644 --- a/app/src/main/java/com/github/iielse/imageviewer/demo/data/Api.kt +++ b/app/src/main/java/com/github/iielse/imageviewer/demo/data/Api.kt @@ -9,9 +9,9 @@ import java.lang.IllegalStateException import kotlin.math.max import kotlin.math.min -// 模拟服务器 +// 模拟数据源仓库 操作管理 class Api( - private val data: MutableList + private val data: MutableList // 源数据 ) { // 模拟网络请求或者本地db查询 上一页 fun asyncQueryBefore(id: Long, pageSize: Int, callback: (List) -> Unit) { @@ -37,9 +37,10 @@ class Api( }, 100) } + // 模拟删除 fun asyncDelete(item: List, callback: ()->Unit) { require( isMainThread()) - data.removeAll(item) // 模拟服务器把数据删掉了 + data.removeAll(item) // 模拟把数据删掉了 Handler(Looper.getMainLooper()).postDelayed({ callback() }, 200) diff --git a/app/src/main/java/com/github/iielse/imageviewer/demo/data/repository.kt b/app/src/main/java/com/github/iielse/imageviewer/demo/data/repository.kt index 56d651e..7711111 100644 --- a/app/src/main/java/com/github/iielse/imageviewer/demo/data/repository.kt +++ b/app/src/main/java/com/github/iielse/imageviewer/demo/data/repository.kt @@ -26,6 +26,7 @@ class TestRepository { requestMore = { request(false) } ) + // 分页加载 fun request(initial: Boolean) { val requestKey = if (initial) -1 else state.nextKey?.toLong() api.asyncQueryAfter(requestKey, PAGE_SIZE) { diff --git a/build.gradle b/build.gradle index cd131a4..9e97c16 100644 --- a/build.gradle +++ b/build.gradle @@ -34,6 +34,6 @@ ext { buildToolsVersion= "30.0.3" minSdkVersion = 21 targetSdkVersion = 31 - versionCode = 218 - versionName = "2.1.8" + versionCode = 219 + versionName = "2.1.9" } \ No newline at end of file diff --git a/imageviewer/src/main/java/com/github/iielse/imageviewer/widgets/video/ExoSourceManager.java b/imageviewer/src/main/java/com/github/iielse/imageviewer/widgets/video/ExoSourceManager.java deleted file mode 100644 index dd732ac..0000000 --- a/imageviewer/src/main/java/com/github/iielse/imageviewer/widgets/video/ExoSourceManager.java +++ /dev/null @@ -1,371 +0,0 @@ -package com.github.iielse.imageviewer.widgets.video; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.net.Uri; - -import androidx.annotation.Nullable; - -import android.text.TextUtils; - -import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.MediaItem; -import com.google.android.exoplayer2.database.DatabaseProvider; -import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory; -import com.google.android.exoplayer2.source.MediaSource; -import com.google.android.exoplayer2.source.ProgressiveMediaSource; -import com.google.android.exoplayer2.source.dash.DashMediaSource; -import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource; -import com.google.android.exoplayer2.source.hls.HlsMediaSource; -import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource; -import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource; -import com.google.android.exoplayer2.upstream.DataSource; -import com.google.android.exoplayer2.upstream.DataSpec; -import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter; -import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; -import com.google.android.exoplayer2.upstream.DefaultHttpDataSource; -import com.google.android.exoplayer2.upstream.RawResourceDataSource; -import com.google.android.exoplayer2.upstream.cache.Cache; -import com.google.android.exoplayer2.upstream.cache.CacheDataSource; -import com.google.android.exoplayer2.upstream.cache.CacheKeyFactory; -import com.google.android.exoplayer2.upstream.cache.CacheSpan; -import com.google.android.exoplayer2.upstream.cache.ContentMetadata; -import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor; -import com.google.android.exoplayer2.upstream.cache.SimpleCache; -import com.google.android.exoplayer2.util.Util; -import com.google.common.base.Ascii; - -import java.io.File; -import java.util.Map; -import java.util.NavigableSet; - -// https://github.com/CarGuo/GSYVideoPlayer/blob/master/gsyVideoPlayer-exo_player2/src/main/java/tv/danmaku/ijk/media/exo2/ExoSourceManager.java -public class ExoSourceManager { - - private static final String TAG = "ExoSourceManager"; - - private static final long DEFAULT_MAX_SIZE = 512 * 1024 * 1024; - - public static final int TYPE_RTMP = 14; - - private static Cache mCache; - /** - * 忽律Https证书校验 - * - * @deprecated 如果需要忽略证书,请直接使用 ExoMediaSourceInterceptListener 的 getHttpDataSourceFactory - */ - @Deprecated - private static boolean sSkipSSLChain = false; - - private static int sHttpReadTimeout = -1; - - private static int sHttpConnectTimeout = -1; - - private Context mAppContext; - - private Map mMapHeadData; - - private String mDataSource; - - private static DatabaseProvider sDatabaseProvider; - - private boolean isCached = false; - - public static ExoSourceManager newInstance(Context context, @Nullable Map mapHeadData) { - return new ExoSourceManager(context, mapHeadData); - } - - private ExoSourceManager(Context context, Map mapHeadData) { - mAppContext = context.getApplicationContext(); - mMapHeadData = mapHeadData; - } - - /** - * @param dataSource 链接 - * @param preview 是否带上header,默认有header自动设置为true - * @param cacheEnable 是否需要缓存 - * @param isLooping 是否循环 - * @param cacheDir 自定义缓存目录 - */ - public MediaSource getMediaSource(String dataSource, boolean preview, boolean cacheEnable, boolean isLooping, File cacheDir, @Nullable String overrideExtension) { - MediaSource mediaSource = null; - - mDataSource = dataSource; - Uri contentUri = Uri.parse(dataSource); - MediaItem mediaItem = MediaItem.fromUri(contentUri); - int contentType = inferContentType(dataSource, overrideExtension); - - String uerAgent = null; - if (mMapHeadData != null) { - uerAgent = mMapHeadData.get("User-Agent"); - } - if ("android.resource".equals(contentUri.getScheme())) { - DataSpec dataSpec = new DataSpec(contentUri); - final RawResourceDataSource rawResourceDataSource = new RawResourceDataSource(mAppContext); - try { - rawResourceDataSource.open(dataSpec); - } catch (RawResourceDataSource.RawResourceDataSourceException e) { - e.printStackTrace(); - } - DataSource.Factory factory = new DataSource.Factory() { - @Override - public DataSource createDataSource() { - return rawResourceDataSource; - } - }; - return new ProgressiveMediaSource.Factory( - factory).createMediaSource(mediaItem); - - } - - switch (contentType) { - case C.TYPE_SS: - mediaSource = new SsMediaSource.Factory( - new DefaultSsChunkSource.Factory(getDataSourceFactoryCache(mAppContext, cacheEnable, preview, cacheDir, uerAgent)), - new DefaultDataSourceFactory(mAppContext, null, - getHttpDataSourceFactory(mAppContext, preview, uerAgent))).createMediaSource(mediaItem); - break; - case C.TYPE_DASH: - mediaSource = new DashMediaSource.Factory(new DefaultDashChunkSource.Factory(getDataSourceFactoryCache(mAppContext, cacheEnable, preview, cacheDir, uerAgent)), - new DefaultDataSourceFactory(mAppContext, null, - getHttpDataSourceFactory(mAppContext, preview, uerAgent))).createMediaSource(mediaItem); - break; - case C.TYPE_HLS: - mediaSource = new HlsMediaSource.Factory(getDataSourceFactoryCache(mAppContext, cacheEnable, preview, cacheDir, uerAgent)) - .setAllowChunklessPreparation(true) - .createMediaSource(mediaItem); - break; - case C.TYPE_OTHER: - default: - mediaSource = new ProgressiveMediaSource.Factory(getDataSourceFactoryCache(mAppContext, cacheEnable, - preview, cacheDir, uerAgent), new DefaultExtractorsFactory()) - .createMediaSource(mediaItem); - break; - } - return mediaSource; - } - - @SuppressLint("WrongConstant") - @C.ContentType - public static int inferContentType(String fileName, @Nullable String overrideExtension) { - fileName = Ascii.toLowerCase(fileName); - if (fileName.startsWith("rtmp:")) { - return TYPE_RTMP; - } else { - return inferContentType(Uri.parse(fileName), overrideExtension); - } - } - - @C.ContentType - public static int inferContentType(Uri uri, @Nullable String overrideExtension) { - return Util.inferContentType(uri, overrideExtension); - } - - /** - * 本地缓存目录 - */ - public static synchronized Cache getCacheSingleInstance(Context context, File cacheDir) { - String dirs = context.getCacheDir().getAbsolutePath(); - if (cacheDir != null) { - dirs = cacheDir.getAbsolutePath(); - } - if (mCache == null) { - String path = dirs + File.separator + "exo"; - boolean isLocked = SimpleCache.isCacheFolderLocked(new File(path)); - if (!isLocked) { - mCache = new SimpleCache(new File(path), new LeastRecentlyUsedCacheEvictor(DEFAULT_MAX_SIZE), sDatabaseProvider); - } - } - return mCache; - } - - public void release() { - isCached = false; - if (mCache != null) { - try { - mCache.release(); - mCache = null; - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - /** - * Cache需要release之后才能clear - */ - public static void clearCache(Context context, File cacheDir, String url) { - try { - Cache cache = getCacheSingleInstance(context, cacheDir); - if (!TextUtils.isEmpty(url)) { - if (cache != null) { - removeCache(cache, url); - } - } else { - if (cache != null) { - for (String key : cache.getKeys()) { - removeCache(cache, key); - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - - public static void removeCache(Cache cache, String url) { - NavigableSet cachedSpans = cache.getCachedSpans(buildCacheKey(url)); - for (CacheSpan cachedSpan : cachedSpans) { - try { - cache.removeSpan(cachedSpan); - } catch (Exception e) { - // Do nothing. - } - } - } - - public static String buildCacheKey(String url) { - DataSpec dataSpec = new DataSpec(Uri.parse(url)); - String key = CacheKeyFactory.DEFAULT.buildCacheKey(dataSpec); - return key; - } - - public static boolean cachePreView(Context context, File cacheDir, String url) { - return resolveCacheState(getCacheSingleInstance(context, cacheDir), url); - } - - public boolean hadCached() { - return isCached; - } - - /** - * 忽律Https证书校验 - * - * @deprecated 如果需要忽略证书,请直接使用 ExoMediaSourceInterceptListener 的 getHttpDataSourceFactory - */ - @Deprecated - public static boolean isSkipSSLChain() { - return sSkipSSLChain; - } - - /** - * 设置https忽略证书 - * - * @param skipSSLChain true时是hulve - * @deprecated 如果需要忽略证书,请直接使用 ExoMediaSourceInterceptListener 的 getHttpDataSourceFactory - */ - @Deprecated - public static void setSkipSSLChain(boolean skipSSLChain) { - sSkipSSLChain = skipSSLChain; - } - - - public static int getHttpReadTimeout() { - return sHttpReadTimeout; - } - - /** - * 如果设置小于 0 就使用默认 8000 MILLIS - */ - public static void setHttpReadTimeout(int httpReadTimeout) { - ExoSourceManager.sHttpReadTimeout = httpReadTimeout; - } - - public static int getHttpConnectTimeout() { - return sHttpConnectTimeout; - } - - /** - * 如果设置小于 0 就使用默认 8000 MILLIS - */ - public static void setHttpConnectTimeout(int httpConnectTimeout) { - ExoSourceManager.sHttpConnectTimeout = httpConnectTimeout; - } - - public static DatabaseProvider getDatabaseProvider() { - return sDatabaseProvider; - } - - public static void setDatabaseProvider(DatabaseProvider databaseProvider) { - ExoSourceManager.sDatabaseProvider = databaseProvider; - } - - /** - * 获取SourceFactory,是否带Cache - */ - private DataSource.Factory getDataSourceFactoryCache(Context context, boolean cacheEnable, boolean preview, File cacheDir, String uerAgent) { - if (cacheEnable) { - Cache cache = getCacheSingleInstance(context, cacheDir); - if (cache != null) { - isCached = resolveCacheState(cache, mDataSource); - CacheDataSource.Factory factory = new CacheDataSource.Factory(); - return factory. - setCache(cache).setCacheReadDataSourceFactory(getDataSourceFactory(context, preview, uerAgent)).setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR); - } - } - return getDataSourceFactory(context, preview, uerAgent); - } - - /** - * 获取SourceFactory - */ - private DataSource.Factory getDataSourceFactory(Context context, boolean preview, String uerAgent) { - return new DefaultDataSourceFactory(context, preview ? null : new DefaultBandwidthMeter.Builder(context).build(), - getHttpDataSourceFactory(context, preview, uerAgent)); - } - - private DataSource.Factory getHttpDataSourceFactory(Context context, boolean preview, String uerAgent) { - if (uerAgent == null) { - uerAgent = Util.getUserAgent(context, TAG); - } - int connectTimeout = DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS; - int readTimeout = DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS; - if (sHttpConnectTimeout > 0) { - connectTimeout = sHttpConnectTimeout; - } - if (sHttpReadTimeout > 0) { - readTimeout = sHttpReadTimeout; - } - boolean allowCrossProtocolRedirects = false; - if (mMapHeadData != null && mMapHeadData.size() > 0) { - allowCrossProtocolRedirects = "true".equals(mMapHeadData.get("allowCrossProtocolRedirects")); - } - DataSource.Factory dataSourceFactory; - dataSourceFactory = new DefaultHttpDataSource.Factory() - .setAllowCrossProtocolRedirects(allowCrossProtocolRedirects) - .setConnectTimeoutMs(connectTimeout) - .setReadTimeoutMs(readTimeout) - .setTransferListener(preview ? null : new DefaultBandwidthMeter.Builder(mAppContext).build()); - if (mMapHeadData != null && mMapHeadData.size() > 0) { - ((DefaultHttpDataSource.Factory) dataSourceFactory).setDefaultRequestProperties(mMapHeadData); - } - return dataSourceFactory; - } - - /** - * 根据缓存块判断是否缓存成功 - */ - private static boolean resolveCacheState(Cache cache, String url) { - boolean isCache = true; - if (!TextUtils.isEmpty(url)) { - String key = buildCacheKey(url); - if (!TextUtils.isEmpty(key)) { - NavigableSet cachedSpans = cache.getCachedSpans(key); - if (cachedSpans.size() == 0) { - isCache = false; - } else { - long contentLength = cache.getContentMetadata(key).get(ContentMetadata.KEY_CONTENT_LENGTH, C.LENGTH_UNSET); - long currentLength = 0; - for (CacheSpan cachedSpan : cachedSpans) { - currentLength += cache.getCachedLength(key, cachedSpan.position, cachedSpan.length); - } - isCache = currentLength >= contentLength; - } - } else { - isCache = false; - } - } - return isCache; - } -} \ No newline at end of file diff --git a/imageviewer/src/main/java/com/github/iielse/imageviewer/widgets/video/ExoVideoView.kt b/imageviewer/src/main/java/com/github/iielse/imageviewer/widgets/video/ExoVideoView.kt index d37f691..42ba201 100644 --- a/imageviewer/src/main/java/com/github/iielse/imageviewer/widgets/video/ExoVideoView.kt +++ b/imageviewer/src/main/java/com/github/iielse/imageviewer/widgets/video/ExoVideoView.kt @@ -8,7 +8,6 @@ import com.google.android.exoplayer2.ExoPlayer import com.google.android.exoplayer2.MediaItem import com.google.android.exoplayer2.Player import com.google.android.exoplayer2.analytics.AnalyticsListener -import com.google.android.exoplayer2.source.MediaSource import com.google.android.exoplayer2.util.EventLogger import com.google.android.exoplayer2.video.VideoSize import kotlin.math.min @@ -135,11 +134,4 @@ open class ExoVideoView @JvmOverloads constructor( super.onDetachedFromWindow() release() } - - override fun onAttachedToWindow() { - super.onAttachedToWindow() - if (exoPlayer == null) { - playUrl?.let(::prepare) - } - } } \ No newline at end of file