背景
使用 SVGA的三方的url播放方式会比较慢,至少延迟3s以上才会出现svga效果,所以改变策略:将线上的svga全部下载到本地进行播放,那么就得将采用网络缓存的方式实现效果。
实现
那么就得实现以下几点:
- 初次下载
- 缓存
- 判重下载
下载的地址就放在这里。这里也是常规的文件路径下载
通过上下文类获取即可,如果参数路径没有,就会再构建一个新的路径下载。
整理的代码如下:
// 获取当前的animation 文件夹String cacheDir = context.getExternalFilesDir(getAnimFilesName()).getAbsolutePath();// 挂个线程new Thread(new Runnable() {@Overridepublic void run() {// 循环当前的礼物svag 获取for (GiftInfo giftInfo : giftInfoList) {/*** 名称规则* 纯 id 加 文件后缀*/String name = giftInfo.getId() + ".svga";File svgaFile = new File(cacheDir, name);// 判断去重if (svgaFile.exists()) {Log.i(TAG, "svgaFile.exists" + svgaFile.getAbsolutePath());continue;}// 网络下载Request request = new Request.Builder().url(giftInfo.getSvga()).build();APIBase.OkHttpInstance.getInstance().newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(@NonNull Call call, @NonNull IOException e) {Log.e(TAG, "svgaFile donwload onFailure" + e.getMessage());// 下载失败的处理giftInfoList.remove(giftInfo);}@Overridepublic void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {if (response.isSuccessful()) {// 将 SVGA 文件保存到缓存目录中FileOutputStream outputStream = new FileOutputStream(svgaFile);outputStream.write(response.body().bytes());outputStream.close();Log.i(TAG, "svgaFile donwload onResponse" + response.message());// 下载成功后,处理逻辑} else {// 下载失败的处理pLog.e(TAG, "svgaFile donwload onResponse" + response.message());giftInfoList.remove(giftInfo);}}});}}}).start();
- 文件存储路径
String cacheDir = context.getExternalFilesDir(getAnimFilesName()).getAbsolutePath();
String name = giftInfo.getId() + ".svga";
File svgaFile = new File(cacheDir, name);
- 判重下载
// 在for 循环下:/*** 名称规则* 纯 id 加 文件后缀*/String name = giftInfo.getId() + ".svga";File svgaFile = new File(cacheDir, name);// 判断去重if (svgaFile.exists()) {Log.i(TAG, "svgaFile.exists" + svgaFile.getAbsolutePath());continue;}
- 网络下载
走okhttp的三方,并通过字节码转化为对应的文件
APIBase.OkHttpInstance.getInstance().newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(@NonNull Call call, @NonNull IOException e) {Log.e(TAG, "svgaFile donwload onFailure" + e.getMessage());// 下载失败的处理giftInfoList.remove(giftInfo);}@Overridepublic void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {if (response.isSuccessful()) {// 将 SVGA 文件保存到缓存目录中FileOutputStream outputStream = new FileOutputStream(svgaFile);outputStream.write(response.body().bytes());outputStream.close();Log.i(TAG, "svgaFile donwload onResponse" + response.message());// 下载成功后,处理逻辑} else {// 下载失败的处理pLog.e(TAG, "svgaFile donwload onResponse" + response.message());giftInfoList.remove(giftInfo);}}});}}}).start();
待优化 线程使用
毕竟这个是挂线程的方式,没有在项目中用到更加稳定的线程处理方式。这是整个的一个遗憾。
所以下面我提供一个思路:可以阅读一下雪峰大佬的文字:
线程池的使用
// 挂个线池ExecutorService service = Executors.newFixedThreadPool(10);// 循环当前的礼物svag 获取for (GiftInfo giftInfo : giftInfoList) {/*** 名称规则* 纯 id 加 文件后缀*/String name = giftInfo.getId() + ".svga";File svgaFile = new File(cacheDir, name);if (svgaFile.exists()) {Log.i(TAG, "svgaFile.exists" + svgaFile.getAbsolutePath());continue;}service.execute(new Runnable() {@Overridepublic void run() {// 网络下载Request request = new Request.Builder().url(giftInfo.getSvga()).build();WendyAPIBase.OkHttpInstance.getInstance().newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(@NonNull Call call, @NonNull IOException e) {Log.e(TAG, "svgaFile donwload onFailure" + e.getMessage());// 下载失败的处理giftInfoList.remove(giftInfo);}@Overridepublic void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {if (response.isSuccessful()) {// 将 SVGA 文件保存到缓存目录中FileOutputStream outputStream = new FileOutputStream(svgaFile);outputStream.write(response.body().bytes());outputStream.close();Log.i(TAG, "svgaFile donwload onResponse" + response.message());// 下载成功后,处理逻辑} else {// 下载失败的处理Log.e(TAG, "svgaFile donwload onResponse" + response.message());giftInfoList.remove(giftInfo);}}});}});}// 记得关闭service.shutdown();
效果如下:
还行~