1. 程式人生 > >okhttp使用,支援斷點續傳

okhttp使用,支援斷點續傳

Android4.4的原始碼中可以看到HttpURLConnection已經替換成OkHttp實現了。所以我們更有理由相信OkHttp的強大。
但是部分api使用仍然需要我們自行封裝才能適應自己的需要,今天對OkHttp做的一些封裝。
封裝okhttp 實現一下功能:
1.實現get,post請求
2.支援上傳,下載功能
3.支援Gson泛型解析json資料
4.使用mvc設計模式
5.支援自定義exception
6.支援自定義controller
7.封裝glide圖片庫使用
8.支援斷點續傳功能
基本滿足日程開發使用

使用方法:android studio中在app的build.gradle中新增依賴
compile project(‘:library’)
具體參考demo

使用介紹:

1.首先需要在專案的application中如下配置:
Cache cache = new Cache(getCacheDir(), 10 * 1024 * 1024);// 配置快取大小
// 程式初始化時,初始okhttp配置 ,可自行定義
OKHttpConfig OKHttpConfig = new OKHttpConfig.Builder().setBaseResponseClass(BaseResponse.class)
.setConnectTimeout(10).setReadTimeout(10).setWriteTimeout(10).setCache(cache).build();
// 初始化
OKHttpManager.init(this, OKHttpConfig);
2.繼承自library重的controller實現自定義載入器:
3.整合greendao實現斷點續傳功能

public abstract class MyAppController<Listener> extends OKHttpController<Listener> {


    public MyAppController() {
        super();
    }

    public MyAppController(Listener l) {
        super();
        setListener(l);
    }

    protected abstract class AppBaseTask<Input, Output
> extends LoadTask<Input, Output> {
@Override public boolean onInterceptor(OKBaseResponse response) { if (response instanceof BaseResponse) { BaseResponse resp = (BaseResponse) response; if (!"10000001".equals(resp.getStatus())) {//101表示成功 // 主執行緒中呼叫onError,不能直接呼叫onError sendMessage(resp.getMessage(), ERROR_CODE); return true; } } return false; } } }

此類是抽象類,具體的子功能可對其繼承實現;
下面提供一個實現demo,具體作用demo中有註釋:

public class LoadController extends MyAppController<LoadController.LoadListener> {

    public LoadController(LoadListener l) {
        mListener = l;
    }

    public void load(LoadRequest request) {
        Task task = new Task();
        task.load(request, LoadResponse.class);
    }

    /**
     * 執行載入任務的task,其回撥都是在主執行緒中呼叫
     * 需要加入請求引數LoadRequest和相應引數LoadResponse
     */
    public class Task extends AppBaseTask<LoadRequest, LoadResponse> {

        @Override
        public IUrl getUrl() {
            // 後去url
            return URLConst.Product.PRODUCTLIST;
        }

        @Override
        public void onSuccess(LoadResponse loadResponse) {
            // 獲得載入成功的相應資料,自動解析成LoadResponse
            mListener.onLoadSuccess(loadResponse);
        }

        @Override
        public void onError(OkException e) {
            // 載入失敗回撥
            mListener.onLoadFail(e);
        }
    }

    /**
     * 載入回撥介面
     */
    public interface LoadListener {

        void onLoadSuccess(LoadResponse loadResponse);

        void onLoadFail(OkException e);
    }
}

以下是斷點下載的管理器程式碼:(參考自)

public class DownloadManager {
private static Context mContext;

private DownloadDao mDownloadDao;
private OkHttpClient mClient;

private int mPoolSize = 5;
// 將執行結果儲存在future變數中
private Map<String, Future> mFutureMap;
private ExecutorService mExecutor;
private Map<String, DownloadTask> mCurrentTaskList;

static DownloadManager manager;

/**
 * 方法加鎖,防止多執行緒操作時出現多個例項
 */
private static synchronized void init() {
    if (manager == null) {
        manager = new DownloadManager();
    }
}

/**
 * 獲得當前物件例項
 *
 * @return 當前例項物件
 */
public final static DownloadManager getInstance() {
    if (manager == null) {
        init();
    }
    return manager;
}

public static void init(Context context) {
    mContext = context;
    getInstance();
}

public DownloadManager() {
    initOkhttpClient();

    // 資料庫初始化
    DaoMaster.OpenHelper openHelper = new DaoMaster.DevOpenHelper(mContext, "downloadDB", null);
    DaoMaster daoMaster = new DaoMaster(openHelper.getWritableDatabase());
    mDownloadDao = daoMaster.newSession().getDownloadDao();

    // 初始化執行緒池
    mExecutor = Executors.newFixedThreadPool(mPoolSize);
    mFutureMap = new HashMap<>();
    mCurrentTaskList = new HashMap<>();
}

/**
 * 初始化okhttp
 */
private void initOkhttpClient() {
    OkHttpClient.Builder okBuilder = new OkHttpClient.Builder();
    okBuilder.connectTimeout(10, TimeUnit.SECONDS);
    okBuilder.readTimeout(10, TimeUnit.SECONDS);
    okBuilder.writeTimeout(10, TimeUnit.SECONDS);
    mClient = okBuilder.build();
}

/**
 * 新增下載任務
 *
 * @param downloadTask
 */
public void addDownloadTask(DownloadTask downloadTask) {
    if (downloadTask != null) {
        downloadTask.setDownloadDao(mDownloadDao);
        downloadTask.setClient(mClient);
        downloadTask.setDownloadStatus(DownloadStatus.DOWNLOAD_STATUS_INIT);
        // 儲存下載task列表
        mCurrentTaskList.put(downloadTask.getId(), downloadTask);
        Future future = mExecutor.submit(downloadTask);
        mFutureMap.put(downloadTask.getId(), future);
    }
}

/**
 * 暫停下載任務
 *
 * @param id 任務id
 */
public void pause(String id) {
    DownloadTask task = mCurrentTaskList.get(id);
    if (task != null) {
        task.setDownloadStatus(DownloadStatus.DOWNLOAD_STATUS_PAUSE);
    }
}

/**
 * 重新開始已經暫停的下載任務
 *
 * @param id 任務id
 */
public void resume(String id) {
    DownloadTask task = mCurrentTaskList.get(id);
    if (task != null) {
        addDownloadTask(task);
    }
}

/**
 * 取消下載任務(同時會刪除已經下載的檔案,和清空資料庫快取)
 *
 * @param id 任務id
 */
public void cancel(String id) {
    DownloadTask task = mCurrentTaskList.get(id);
    if (task != null) {
        mCurrentTaskList.remove(id);
        mFutureMap.remove(id);
        task.cancel();
        task.setDownloadStatus(DownloadStatus.DOWNLOAD_STATUS_CANCEL);
    }
}

/**
 * 實時更新manager中的task資訊
 *
 * @param task
 */
public void updateDownloadTask(DownloadTask task) {
    if (task != null) {
        DownloadTask currTask = mCurrentTaskList.get(task.getId());
        if (currTask != null) {
            mCurrentTaskList.put(task.getId(), task);
        }
    }
}

/**
 * 獲得指定的task
 *
 * @param id task id
 * @return
 */
public DownloadTask getDownloadTask(String id) {
    DownloadTask currTask = mCurrentTaskList.get(id);
    return currTask;
}

/**
 * 獲得所有的task
 *
 * @return
 */
public Map<String, DownloadTask> getAllDownloadTasks() {
    return mCurrentTaskList;
}

}

之後就可在Activity或fragment中進行例項呼叫了,更多功能請參考demo和原始碼,就這麼實現網路請求。

這裡寫圖片描述
這裡寫圖片描述

下面提供專案原始碼和demo供參考最新程式碼請參考github中專案;不足之處請各位多多指教,留言。。。
demo下載地址github
csdn下載地址