(原创)接口隔离原则封装一个自己的网络请求库(四)文件下载功能

继续完善一个下载文件功能

首先,在我们的基础接口INetManager里新增方法

代码如下:

/**
 * Created by lenovo on 2019/11/8.
 * 网络请求工具类
 */
public interface INetManager {

    /**
     * @param url      请求网址
     * @param callback 回调
     * @param tag      请求的tag
     */
    void get(String url, INetGetCallBack callback, Object tag);

    /**
     * post请求
     *
     * @param url
     * @param headersParam head
     * @param param        参数
     * @param callback     回调
     * @param tag          请求的tag
     */
    void post(String url, Map<String, String> headersParam, Map<String, String> param, INetPostCallBack callback, Object tag);

    /**
     * 下载文件
     *
     * @param url
     * @param file  下载的文件
     * @param callback 回调
     * @param tag      tag
     */
    void downFile(String url, File file, INetDownFileCallBack callback, Object tag);


    /**
     * 取消请求
     *
     * @param tag
     */
    void cancel(Object tag);


}

这一次新增一个downFile功能,传入url和下载的File,新建一个下载文件的回调,最后是请求的tag

INetDownFileCallBack代码如下

/**
 * Created by lenovo on 2019/11/9.
 * 下载文件的返回结果
 */

public interface INetDownFileCallBack {


    void success(File file);

    //下载进度
    void progress(int progress);

    void failed(Throwable throwable);
}

这次新增了一个progress方法

顾名思义,是用来传递下载进度的

然后,就是关键的OkhttpNetManager里的功能实现了

这边也直接上代码吧

    @Override
    public void downFile(String url, final File file, final INetDownFileCallBack callback, Object tag) {
        if (!file.exists()) {//如果文件不存在,先创建路径
            file.getParentFile().mkdirs();
        }
        Request.Builder builder = new Request.Builder();
        Request request = builder.url(url).get().tag(tag).build();
        Call call = sokHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, final IOException e) {
                if (call.isCanceled()) {
                    return;
                }
                //非ui线程
                shandler.post(new Runnable() {
                    @Override
                    public void run() {
                        //ui线程
                        callback.failed(e);
                    }
                });

            }

            @Override
            public void onResponse(final Call call, Response response) throws IOException {
                InputStream is = null;
                OutputStream os = null;

                try {

                    final long totalLen = response.body().contentLength();

                    is = response.body().byteStream();
                    os = new FileOutputStream(file);

                    byte[] buffer = new byte[8 * 1024];
                    long curLen = 0;
                    int bufferLen = 0;
                    while (!call.isCanceled() && (bufferLen = is.read(buffer)) != -1) {
                        os.write(buffer, 0, bufferLen);
                        os.flush();
                        curLen += bufferLen;
                        final long finalCurLen = curLen;
                        shandler.post(new Runnable() {
                            @Override
                            public void run() {
                                //传递下载进度
                                callback.progress((int) (finalCurLen * 1.0f / totalLen * 100));
                            }
                        });
                    }
                    if (call.isCanceled()) {
                        return;
                    }
                    shandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callback.success(file);
                        }
                    });
                } catch (final Throwable e) {
                    if (call.isCanceled()) {
                        return;
                    }
                    //非ui线程
                    shandler.post(new Runnable() {
                        @Override
                        public void run() {
                            //ui线程
                            callback.failed(e);
                        }
                    });
                } finally {
                    if (is != null) {
                        is.close();
                    }
                    if (os != null) {
                        os.close();
                    }
                }
            }
        });
    }

这些功能做完后,就是具体的使用了

记得加上文件读写权限

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

这里就不写动态申请权限的代码了

使用方法如下:

先创建一个File文件,这就是设置你下载下来的文件位置和名称

这里默认用存储卡的根目录

        File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "测试文件.apk");

然后进行下载即可

        INetClient.getsInstance()
                .getmNetManager()
                .downFile(url,file,回调,tag);

这边的回调多了一个progress方法

就是用来显示下载进度的

可以配合SeekBar等控件进行显示

下载完成后会调用success方法

最后,你也可以测试一下之前的cancle方法

开始下载后执行取消下载的请求

看下是否会停止下载

这边是没有实现断点下载的

有需要的朋友可以查阅相关资料

自己去完善这部分功能

猜你喜欢

转载自blog.csdn.net/Android_xiong_st/article/details/103032077
今日推荐