[Android開發] 使用okhttp下載檔案(帶監聽)
阿新 • • 發佈:2019-01-10
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) {
//進度返回
}
}