Android 開發 框架系列 OkHttp文件下載功能實現(含斷點續傳)


前言

  此篇博客只是下載功能的記錄demo,如果你還不太了解okhttp可以參考我的另一篇博客 https://www.cnblogs.com/guanxinjing/p/9708575.html

代碼部分

 

package okhttpdemo.com.libs.net.httpBase;
import android.util.Log;
import org.json.JSONObject;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttpdemo.com.libs.net.httpBase.listener.HttpDownListener;
/**
 *@content: okhttp的下載功能工具類 (分別包含:1.無斷點續傳的get下載 2.有斷點續傳的get下載 3.無斷點續傳的post下載 4.有斷點續傳的post下載)
 *@time:2018-12-12
 *@build:z
 */

public class OkHttpDownUtil {
    private static final String TAG = "OkHttpDownUtil";
    private Call mCall;
    private long mAlreadyDownLength = 0;//已經下載長度
    private long mTotalLength = 0;//整體文件大小
    private int mSign = 0; //標記當前運行的是那個方法
    private String mDownUrl;//下載網絡地址
    private File mPath;//文件保存路徑
    private JSONObject mJson;
    private HttpDownListener mHttpDownListener;//下載進度接口回調


    /**
     * 沒有斷點續傳功能的get請求下載
     * @param downUrl 下載網絡地址
     * @param saveFilePathAndName 保存路徑
     */
    public void getDownRequest(final String downUrl, final File saveFilePathAndName, final HttpDownListener listener) {
        mSign = 1;
        mDownUrl = downUrl;
        mPath = saveFilePathAndName;
        mHttpDownListener = listener;
        mAlreadyDownLength = 0;
        Request request = new Request.Builder()
                .url(mDownUrl)
                .get()
                .build();
        mCall = OkHttpClientCreate.CreateClient().newCall(request);//構建了一個完整的http請求
        mCall.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                if (mHttpDownListener != null) {
                    mHttpDownListener.onFailure(call, e);
                }

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                ResponseBody responseBody = response.body();
                mTotalLength = responseBody.contentLength();//下載文件的總長度
                InputStream inp = responseBody.byteStream();
                FileOutputStream fileOutputStream = new FileOutputStream(mPath);
                try {
                    byte[] bytes = new byte[2048];
                    int len = 0;
                    while ((len = inp.read(bytes)) != -1) {
                        mAlreadyDownLength = mAlreadyDownLength + len;
                        fileOutputStream.write(bytes, 0, len);
                        if (mHttpDownListener != null) {
                            mHttpDownListener.onResponse(call, response, mTotalLength, mAlreadyDownLength);
                        }

                    }
                } catch (Exception e) {
                    Log.e(TAG, "Get下載異常");

                } finally {
                    fileOutputStream.close();
                    inp.close();
                    Log.e(TAG, "流關閉");
                }
            }
        });
    }

    /**
     * 有斷點續傳功能的get下載
     * @param downUrl 下載地址
     * @param saveFilePathAndName 保存路徑
     * @param listener 進度監聽
     */
    public void getRenewalDownRequest(final String downUrl, final File saveFilePathAndName, final HttpDownListener listener){
            mSign = 2;
            mDownUrl = downUrl;
            mPath = saveFilePathAndName;
            mHttpDownListener = listener;
            Request request = new Request.Builder()
                    .url(mDownUrl)
                    .header("RANGE", "bytes=" + mAlreadyDownLength + "-")
                    .build();
            mCall = OkHttpClientCreate.CreateClient().newCall(request);//構建了一個完整的http請求
            mCall.enqueue(new Callback() { //發送請求
                @Override
                public void onFailure(Call call, IOException e) {
                    if (mHttpDownListener != null) {
                        mHttpDownListener.onFailure(call, e);
                    }
                    Log.e(TAG, "onFailure: 異常報錯=" + e.toString());

                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    ResponseBody responseBody = response.body();
                    InputStream inputStream = responseBody.byteStream();//得到輸入流
                    RandomAccessFile randomAccessFile = new RandomAccessFile(mPath, "rw");//得到任意保存文件處理類實例
                    if (mTotalLength == 0){
                        mTotalLength = responseBody.contentLength();//得到文件的總字節大小
                        randomAccessFile.setLength(mTotalLength);//預設創建一個總字節的占位文件
                    }
                    if (mAlreadyDownLength != 0){
                        randomAccessFile.seek(mAlreadyDownLength);
                    }
                    byte[] bytes = new byte[2048];
                    int len = 0;
                    try {
                        while ((len = inputStream.read(bytes)) != -1) {
                            randomAccessFile.write(bytes,0,len);
                            mAlreadyDownLength = mAlreadyDownLength + len;
                            if (mHttpDownListener != null) {
                                mHttpDownListener.onResponse(call, response, mTotalLength, mAlreadyDownLength);
                            }
                        }

                    } catch (Exception e) {
                        Log.e(TAG, "Get下載異常");

                    } finally {
                        mAlreadyDownLength = randomAccessFile.getFilePointer();//記錄當前保存文件的位置
                        randomAccessFile.close();
                        inputStream.close();
                        Log.e(TAG, "流關閉 下載的位置="+mAlreadyDownLength);
                    }

                }
            });
    }

    /**
     * 沒有斷點續傳的post下載
     * @param downUrl
     * @param saveFilePathAndName
     * @param json
     * @param listener
     */
    public void postDownRequest(final String downUrl, final File saveFilePathAndName, final JSONObject json,final HttpDownListener listener){
           mSign = 3;
           mDownUrl = downUrl;
           mPath = saveFilePathAndName;
           mJson = json;
           mHttpDownListener = listener;
           mAlreadyDownLength = 0;
           Request request = new Request.Builder()
                   .url(mDownUrl)
                   .post(changeJSON(json))
                   .build();
           mCall = OkHttpClientCreate.CreateClient().newCall(request);
           mCall.enqueue(new Callback() {
               @Override
               public void onFailure(Call call, IOException e) {
                   if (mHttpDownListener!=null){
                       mHttpDownListener.onFailure(call,e);
                   }
               }

               @Override
               public void onResponse(Call call, Response response) throws IOException {

                   ResponseBody responseBody = response.body();
                   mTotalLength = responseBody.contentLength();
                   InputStream inputStream = responseBody.byteStream();
                   FileOutputStream fileOutputStream = new FileOutputStream(mPath);
                   byte[] bytes = new byte[2048];
                   int len = 0;
                   try {
                       while ((len = inputStream.read(bytes)) != -1) {
                           fileOutputStream.write(bytes, 0, len);
                           mAlreadyDownLength = mAlreadyDownLength + len;
                           if (mHttpDownListener != null) {
                               mHttpDownListener.onResponse(call, response, mTotalLength, mAlreadyDownLength);
                           }
                       }
                   }catch (Exception e){
                       Log.e(TAG, "Post下載異常");
                   }finally {
                       fileOutputStream.close();
                       inputStream.close();
                       Log.e(TAG, "流關閉");

                   }

               }

           });

    }

    /**
     * 支持斷點續傳的post下載
     * @param downUrl 下載網址
     * @param saveFilePathAndName 文件保存路徑
     * @param json 參數
     * @param listener 接口回調
     */
    public void postRenewalDownRequest(final String downUrl, final File saveFilePathAndName, final JSONObject json, final HttpDownListener listener){
            mSign = 4;
            mDownUrl = downUrl;
            mPath = saveFilePathAndName;
            mJson = json;
            mHttpDownListener = listener;
            Request request = new Request.Builder()
                    .url(mDownUrl)
                    .header("RANGE","bytes="+mAlreadyDownLength+"-")
                    .post(changeJSON(json))
                    .build();
            mCall = OkHttpClientCreate.CreateClient().newCall(request);
            mCall.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    if (mHttpDownListener != null){
                        mHttpDownListener.onFailure(call,e);
                    }
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    ResponseBody responseBody = response.body();
                    InputStream inputStream = responseBody.byteStream();
                    RandomAccessFile randomAccessFile = new RandomAccessFile(mPath,"rw");
                    if (mTotalLength == 0){
                        mTotalLength = responseBody.contentLength();
                        randomAccessFile.setLength(mTotalLength);
                    }
                    if (mAlreadyDownLength!=0){
                        randomAccessFile.seek(mAlreadyDownLength);
                    }
                    byte[] bytes = new byte[2048];
                    int len = 0;
                    try {
                        while ((len = inputStream.read(bytes)) != -1) {
                            randomAccessFile.write(bytes, 0, len);
                            mAlreadyDownLength = mAlreadyDownLength + len;
                            if (mHttpDownListener != null) {
                                mHttpDownListener.onResponse(call, response, mTotalLength, mAlreadyDownLength);
                            }

                        }
                    }catch (Exception e){
                        Log.e(TAG, "Post下載異常");

                    }finally {
                        mAlreadyDownLength = randomAccessFile.getFilePointer();
                        randomAccessFile.close();
                        inputStream.close();
                        Log.e(TAG, "流關閉 下載的位置="+mAlreadyDownLength);
                    }

                }
            });
    }

    /**
     * 恢復下載
     */
    public void resume(){
        if (mSign==0){
            return;
        }
        switch (mSign){
            case 1:
                getDownRequest(mDownUrl,mPath,mHttpDownListener);
                break;
            case 2:
                getRenewalDownRequest(mDownUrl,mPath,mHttpDownListener);
                break;
            case 3:
                postDownRequest(mDownUrl,mPath,mJson,mHttpDownListener);
                break;
            case 4:
                postRenewalDownRequest(mDownUrl,mPath,mJson,mHttpDownListener);
                break;
            default:
                break;
        }

    }

    /**
     * 暫停下載
     */
    public void stop(){
        if (mCall!=null){
            mCall.cancel();
        }

    }

    /**
     * 刪除下載文件
     */
    public void deleteCurrentFile(){
        if (mPath == null){
            Log.e(TAG, "deleteCurrentFile error : 沒有路徑");
            return;
        }
        if (!mPath.exists()){
            Log.e(TAG, "deleteCurrentFile error: 文件不存在");
            return;
        }
        mPath.delete();
        mAlreadyDownLength = 0;
        mTotalLength = 0;
        mSign = 0;
    }

    /**
     * 銷毀
     */
    public void destroy(){
        if (mCall!=null){
            mCall.cancel();
            mCall = null;
        }
        mSign = 0;
        mDownUrl = null;
        mPath = null;
        mHttpDownListener = null;
        mAlreadyDownLength = 0;
        mTotalLength = 0;
    }

    /**
     * 轉換Json參數為RequestBody
     * @param jsonParam json對象
     * @return RequestBody
     */
    private RequestBody changeJSON(JSONObject jsonParam){
        RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8")
                , String.valueOf(jsonParam));
        return requestBody;
    }

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM