【Android】线程下载资源保证资源到位采用了 OkHttp的三方网络下载 & 文件缓存策略

背景

使用 SVGA的三方的url播放方式会比较慢,至少延迟3s以上才会出现svga效果,所以改变策略:将线上的svga全部下载到本地进行播放,那么就得将采用网络缓存的方式实现效果。
【Android】线程下载资源保证资源到位采用了 OkHttp的三方网络下载 & 文件缓存策略_第1张图片

实现

那么就得实现以下几点:

  • 初次下载
  • 缓存
  • 判重下载

下载的地址就放在这里。这里也是常规的文件路径下载

【Android】线程下载资源保证资源到位采用了 OkHttp的三方网络下载 & 文件缓存策略_第2张图片

通过上下文类获取即可,如果参数路径没有,就会再构建一个新的路径下载。
整理的代码如下:

  // 获取当前的animation 文件夹
        String cacheDir = context.getExternalFilesDir(getAnimFilesName()).getAbsolutePath();

        // 挂个线程
        new Thread(new Runnable() {
            @Override
            public 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() {
                        @Override
                        public void onFailure(@NonNull Call call, @NonNull IOException e) {
                            Log.e(TAG, "svgaFile donwload onFailure" + e.getMessage());
                            // 下载失败的处理
                            giftInfoList.remove(giftInfo);
                        }

                        @Override
                        public 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() {
                        @Override
                        public void onFailure(@NonNull Call call, @NonNull IOException e) {
                            Log.e(TAG, "svgaFile donwload onFailure" + e.getMessage());
                            // 下载失败的处理
                            giftInfoList.remove(giftInfo);
                        }

                        @Override
                        public 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() {
                @Override
                public void run() {
                    // 网络下载
                    Request request = new Request.Builder()
                            .url(giftInfo.getSvga())
                            .build();

                    WendyAPIBase.OkHttpInstance.getInstance().newCall(request).enqueue(new Callback() {
                        @Override
                        public void onFailure(@NonNull Call call, @NonNull IOException e) {
                            Log.e(TAG, "svgaFile donwload onFailure" + e.getMessage());
                            // 下载失败的处理
                            giftInfoList.remove(giftInfo);
                        }

                        @Override
                        public 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();

效果如下:
还行~
【Android】线程下载资源保证资源到位采用了 OkHttp的三方网络下载 & 文件缓存策略_第3张图片

你可能感兴趣的:(android代码小结,知识分享,代码备忘录,android,okhttp,网络)