1. 程式人生 > >[Android開發] 使用okhttp下載檔案(帶監聽)

[Android開發] 使用okhttp下載檔案(帶監聽)

DownloadManager.java

package com.minstone.mdoctor.tool.net;

import android.os.Handler;
import android.os.Looper;

import com.minstone.util.LogUtil;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import
com.squareup.okhttp.Response; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import static com.minstone.util.FileAccessor.getFileName; /** * Created by LITP on 2016/9/26. */
public class DownloadManager { public DownloadManager() { mDelivery = new Handler(Looper.getMainLooper()); } private Handler mDelivery; //主執行緒返回 private Call downCall; //下載的call private static OkHttpClient mOkHttpClient; private static DownloadManager mInstance; //單例
public static DownloadManager getInstance() { if (mInstance == null) { synchronized (OkHttpManager.class) { if (mInstance == null) { mInstance = new DownloadManager(); } } } return mInstance; } //synchronized修飾的靜態方法鎖定的是這個類的所有物件,保證在同一時刻最多隻有一個執行緒執行該段程式碼 public synchronized OkHttpClient getOkHttpClient() { if (null == mOkHttpClient) { try { mOkHttpClient = newOkHttpClient(); } catch (Exception e) { e.printStackTrace(); } } return mOkHttpClient; } /** * 建立okhttp * * @return * @throws Exception */ private OkHttpClient newOkHttpClient() throws Exception { //建立okHttpClient物件 OkHttpClient mOkHttpClient = new OkHttpClient(); TrustManager tm = new OkHttpManager.myTrustManager(); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[]{tm}, null); mOkHttpClient.setSslSocketFactory(sslContext.getSocketFactory()); return mOkHttpClient; } /** * 非同步下載檔案 * * @param url 檔案的下載地址 * @param destFileDir 本地檔案儲存的資料夾 * @param callback */ private void okHttpDownload(final String url, final String destFileDir, final ResultCallback callback) { final Request request = new Request.Builder() .url(url) .build(); downCall = getOkHttpClient().newCall(request); downCall.enqueue(new Callback() { @Override public void onFailure(final Request request, final IOException e) { sendFailedStringCallback(request, e, callback); } @Override public void onResponse(Response response) { InputStream is = null; byte[] buf = new byte[2048]; int len = 0; FileOutputStream fos = null; try { double current = 0; double total = response.body().contentLength(); is = response.body().byteStream(); File file = new File(destFileDir, getFileName(url)); fos = new FileOutputStream(file); while ((len = is.read(buf)) != -1) { current += len; fos.write(buf, 0, len); LogUtil.w("download current------>" + current); sendProgressCallBack(total, current, callback); } fos.flush(); //如果下載檔案成功,第一個引數為檔案的絕對路徑 sendSuccessResultCallback(file.getAbsolutePath(), callback); } catch (IOException e) { sendFailedStringCallback(response.request(), e, callback); } finally { try { if (is != null) is.close(); } catch (IOException e) { e.printStackTrace(); } try { if (fos != null) fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }); } //下載失敗ui執行緒回撥 private void sendFailedStringCallback(final Request request, final Exception e, final ResultCallback callback) { mDelivery.post(new Runnable() { @Override public void run() { if (callback != null) callback.onError(request, e); } }); } //下載成功ui執行緒回撥 private void sendSuccessResultCallback(final Object object, final ResultCallback callback) { mDelivery.post(new Runnable() { @Override public void run() { if (callback != null) { callback.onResponse(object); } } }); } //下載回撥介面 public static abstract class ResultCallback<T> { //下載錯誤 public abstract void onError(Request request, Exception e); //下載成功 public abstract void onResponse(T response); //下載進度 public abstract void onProgress(double total, double current); } /** * 進度資訊ui執行緒回撥 * * @param total 總計大小 * @param current 當前進度 * @param callBack * @param <T> */ private <T> void sendProgressCallBack(final double total, final double current, final ResultCallback<T> callBack) { mDelivery.post(new Runnable() { @Override public void run() { if (callBack != null) { callBack.onProgress(total, current); } } }); } /* 下面為對外開放介面 */ /** * 下載檔案 * * @param url 檔案連結 * @param destDir 下載儲存地址 * @param callback 回撥 */ public static void downloadFile(String url, String destDir, ResultCallback callback) { getInstance().okHttpDownload(url, destDir, callback); } /** * 取消下載 */ public static void cancleDown(){ getInstance().downCall.cancel(); } }

使用:


    private void startDown(){
        String apkUrl = "apk下載的連結";
        String fileUrl = Environment.getExternalStorageDirectory().getAbsolutePath();
        DownloadManager.downloadFile(apkUrl,fileUrl,new DownloadCallBack());
    }


    //監聽類
    class DownloadCallBack extends DownloadManager.ResultCallback {

        @Override
        public void onError(Request request, Exception e) {
            //下載失敗返回
        }

        @Override
        public void onResponse(Object response) {
            //下載成功返回
        }

        @Override
        public void onProgress(double total, double current) {
            //進度返回
        }
    }