okgo網絡請求框架的實現


第一步:添加依賴:

    implementation 'com.lzy.net:okgo:3.0.4'
    implementation 'com.lzy.net:okrx2:2.0.2'
    implementation 'com.lzy.net:okserver:2.0.5'

第二步: 創建HttpManager:示例:

import android.content.Context;

import com.lzy.okgo.OkGo;
import com.shiwen.oil.bean.result.DailyDataResult;
import com.shiwen.oil.constant.HttpUrlConstants;
import com.shiwen.oil.util.JsonParseUtil;

import org.json.JSONObject;

/**
 * 網絡請求管理類
 */
public class HttpManager {
    private volatile static HttpManager instance;

    private HttpManager(Context mContext) {
    }

    public static HttpManager getInstance(Context mContext) {
        if (instance == null) {
            synchronized (HttpManager.class) {
                if (instance == null) {
                    instance = new HttpManager(mContext);
                }
            }
        }
        return instance;
    }
 
    public void getDialyData( String ksrq, HttpStringResponseHandler<DailyDataResult> handler) {
        OkGo.<String>post(HttpUrlConstants.HTTP_URL + HttpUrlConstants.DAILY_DATA_URL)
                .params("ksrq",ksrq)
                .execute(handler);
    }


    public void getLoanOrderLists(GetLoanOrderParams postParams, Context context, HttpStringResponseHandler<GetLoanOrderListsResult> handler) {
        JSONObject jsonRequest = JsonParseUtil.beanParseJson(HttpUrlConstants.GETLOANORDERLIST, postParams, context);
        OkGo.<String>post(HttpUrlConstants.HTTP_URL + HttpUrlConstants.GETLOANORDERLIST)
                .upJson(jsonRequest)
                .execute(handler);
    }
  public void loanImg(File file, Context context, HttpStringResponseHandler<LoanImgResult> handler) {
        FileUtils.compressImageToFile(file);
        OkGo.<String>post(HttpUrlConstants.HTTP_URL + HttpUrlConstants.LOANIMG)
                .params("userid", ConfigConstants.getUid(context))
                .params("image", file)
                .execute(handler);
    }
 
         

 


}

第三步:創建JsonParseUtil:

import android.content.Context;

import com.google.gson.Gson;
import com.google.gson.JsonParseException;

import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class JsonParseUtil {
    private static ObjectMapper objectMapper = new ObjectMapper();

    public JsonParseUtil() {
    }

    public static JSONObject beanParseJson(String method, Object request, Context mContext) {
        Gson gson = new Gson();
        JSONObject json = null;
        try {
            if (request != null) {
                json = new JSONObject(gson.toJson(request));
            } else {
                json = new JSONObject();
            }

//            json.put("userid", ConfigConstants.getToken(mContext));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return json;
    }


    public static Object jsonParseResponse(JSONObject json, Class... responses) {
        Object obj = null;
        if (responses.length > 1) {
            try {
                obj = responses[0].newInstance();
                Field[] var6;
                int var5 = (var6 = responses[0].getDeclaredFields()).length;

                for (int var4 = 0; var4 < var5; ++var4) {
                    Field e = var6[var4];
                    if (!e.getType().isAssignableFrom(ArrayList.class)) {
                        Method var20 = responses[0].getMethod(ReflectUtil.setterNameFromField(e), new Class[]{e.getType()});
                        var20.invoke(obj, new Object[]{json.get(e.getName())});
                    } else {
                        JSONArray m = json.getJSONArray(e.getName());
                        Object[] objects = (Object[]) Array.newInstance(responses[1], m.length());

                        for (int list = 0; list < objects.length; ++list) {
                            objects[list] = jsonParseResponse(m.getJSONObject(list), (Class[]) Arrays.copyOfRange(responses, 1, responses.length));
                        }

                        List var21 = asList(objects);
                        Method m1 = responses[0].getMethod(ReflectUtil.setterNameFromField(e), new Class[]{var21.getClass()});
                        m1.invoke(obj, new Object[]{var21});
                    }
                }
            } catch (InstantiationException var14) {
                var14.printStackTrace();
            } catch (IllegalAccessException var15) {
                var15.printStackTrace();
            } catch (JSONException var16) {
                var16.printStackTrace();
            } catch (NoSuchMethodException var17) {
                var17.printStackTrace();
            } catch (IllegalArgumentException var18) {
                var18.printStackTrace();
            } catch (InvocationTargetException var19) {
                var19.printStackTrace();
            }
        } else {
            try {
                obj = objectMapper.readValue(json.toString(), responses[0]);
            } catch (JsonParseException var11) {
                var11.printStackTrace();
            } catch (JsonMappingException var12) {
                var12.printStackTrace();
            } catch (IOException var13) {
                var13.printStackTrace();
            }
        }

        return obj;
    }

    public static <T> List<T> asList(T... a) {
        ArrayList list = new ArrayList();
        Collections.addAll(list, a);
        return list;
    }
}

第四步創建:HttpStringResponseHandler

import android.content.Context;

import com.google.gson.Gson;
import com.lzy.okgo.callback.StringCallback;
import com.lzy.okgo.model.Response;
import com.lzy.okgo.request.base.Request;
import com.shiwen.oil.util.GsonUtil;
import com.shiwen.oil.util.LoggerUtil;
import com.shiwen.oil.widget.ProgressDialog;
/**
 * 網絡請求返回處理類
 */
public abstract class HttpStringResponseHandler<T> extends StringCallback {
    private static final String TAG = "HttpStringResponseHandler";
    private Context context;
    private Class<T> cls;
    private boolean isNeedParse;
    private boolean isNeedProgress;
    /**
     * 不需要解析時使用
     *
     * @param context
     * @param isNeedProgress
     */
    public HttpStringResponseHandler(Context context, boolean isNeedProgress) {
        this.context = context;
        this.isNeedProgress = isNeedProgress;
    }

    /**
     * 需要解析時,使用
     *
     * @param context
     * @param cls
     * @param isNeedParse
     * @param isNeedProgress
     */
    public HttpStringResponseHandler(Context context, Class<T> cls, boolean isNeedParse, boolean isNeedProgress) {
        this.context = context;
        this.cls = cls;
        this.isNeedParse = isNeedParse;
        this.isNeedProgress = isNeedProgress;
    }
    @Override
    public void onStart(Request<String, ? extends Request> request) {
        if (isNeedProgress && context != null)
            ProgressDialog.getInstance().startProgressDialog(context, "加載中");
    }

    @Override
    public void onFinish() {
        if (isNeedProgress)
            ProgressDialog.getInstance().stopProgressDialog();
    }
    @Override
    public void onError(Response<String> response) {
        LoggerUtil.e("網絡訪問異常,請檢查網絡!" + response.toString());
        onFaile("網絡訪問異常,請檢查網絡!");
        if (isNeedProgress)
            ProgressDialog.getInstance().stopProgressDialog();
    }

    @Override
    public void onSuccess(/*String response, int id*/Response<String> response) {
        LoggerUtil.e("onResponse = " + response.body());
        if (isNeedProgress)
            ProgressDialog.getInstance().stopProgressDialog();

        if (isNeedParse) {
            try {

                Gson gson = GsonUtil.getInstance();
                T result = gson.fromJson(response.body().trim(), cls);
                onSuccess(result);
            } catch (Exception e) {
                onFaile("數據錯誤!");
                LoggerUtil.e("onSuccess Exception : " + e.toString() + "    ");
                e.printStackTrace();
            }

        } else {
            onSuccessWithNoparse(response.body());
        }
    }

    /**
     * 需要解析時的回調
     *
     * @param t
     */
    public void onSuccess(T t) {
        LoggerUtil.systemOut(t.toString());
    }


    /**
     * 不需要解析時的回調
     *
     * @param result
     */
    public void onSuccessWithNoparse(String result) {
    }

    /**
     * 失敗的回調
     *
     * @param res
     */
    public void onFaile(String res) {
        LoggerUtil.systemOut("http  onFaile ---> "+res);
    }
}

第五步,代碼中使用:

    private void getDailyDatefromNet() {
        refreshLayout.setRefreshing(true);
        String ksrq = tvDate.getText().toString().trim();
        HttpManager.getInstance(getActivity()).getDialyData(ksrq, new HttpStringResponseHandler<DailyDataResult>(getActivity(), DailyDataResult.class, true, false) {
            @Override
            public void onSuccess(DailyDataResult dailyDataResult) {

                super.onSuccess(dailyDataResult);
                 
            }

            @Override
            public void onFaile(String res) {
                super.onFaile(res);
          
            }

            @Override
            public void onError(Response<String> response) {
                super.onError(response);
       
            }
        });
    }

示例2:圖片上傳:

 HttpManager.getInstance(DataActivity.this).loanImg(new File(cropImagePath), LoanDataStep1Activity.this, new HttpStringResponseHandler<LoanImgResult>(LoanDataStep1Activity.this, LoanImgResult.class, true, true) {
                @Override
                public void onSuccess(final LoanImgResult response) {
                    super.onSuccess(response);
                    
                }
            });

文件下載OkDownload

OkGo與OkDownload的區別就是,OkGo只是簡單的做一個下載功能,不具備斷點下載,暫停等操作,但是這在很多時候已經能滿足需要了。
而有些app需要有一個下載列表的功能,就像迅雷下載一樣,每個下載任務可以暫停,可以繼續,可以重新下載,可以有下載優先級,這時候OkDownload就有用了。

  • 結合OkGo的request進行網絡請求,支持與OkGo保持相同的配置方法和傳參方式
  • 支持斷點下載,支持突然斷網,強殺進程后,繼續斷點下載
  • 每個下載任務具有無狀態、下載、暫停、等待、出錯、完成共六種狀態
  • 所有下載任務按照tag區分,切記不同的任務必須使用不一樣的tag,否者斷點會發生錯亂
  • 相同的下載url地址,如果使用不一樣的tag,也會認為是兩個下載任務
  • 不同的下載url地址,如果使用相同的tag,會認為是同一個任務,導致斷點錯亂
  • 默認同時下載數量為3個,默認下載路徑/storage/emulated/0/download,下載路徑和下載數量都可以在代碼中配置
  • 下載文件名可以自己定義,也可以不傳,讓框架自動獲取文件名

簡單實現代碼:

 HttpManager.getInstance(this).downloadFile(new DownloadListener("tasgTag") {
            @Override
            public void onStart(Progress progress) {
                LoggerUtil.systemOut(progress+"progress");
            }

            @Override
            public void onProgress(Progress progress) {
                LoggerUtil.systemOut(progress+"progress");
            }

            @Override
            public void onError(Progress progress) {
                LoggerUtil.systemOut(progress+"progress");
            }

            @Override
            public void onFinish(File file, Progress progress) {
                LoggerUtil.systemOut(progress+"progress");
            }

            @Override
            public void onRemove(Progress progress) {
                LoggerUtil.systemOut(progress+"progress");
            }
        });
    /**
     * 下載
     *
     * @param
     */
    public void downloadFile(DownloadListener downloadListener) {

        Request<File, ? extends Request> request = OkGo.<File>get("http://192.168.0.195:8088/test.apk");
        OkDownload.getInstance().request("tasgTag", request)
                .fileName("test.apk")
                .folder(CommonConstants.appDir.getPath())
                .save()
                .register(downloadListener)
                .start();
    }
  1. 構建一個下載請求Request,這個構建方法和OkGo是一樣的,params參數和headers參數是只是演示使用,一切OkGo的使用方法,這里都是一樣的。
  2. 構建下載任務,使用OkDownload中的request方法,傳入一個tag和我們上一步創建的request對象,創建出下載任務,其他的方法我們下文在細講。
  3. 啟動任務,我們已經得到了DownloadTask任務對象,那么簡單調用start啟動他就好了,同時他還支持這么幾個方法:
    • start():開始一個新任務,或者繼續下載暫停的任務都是這個方法
    • pause():將一個下載中的任務暫停
    • remove():移除一個任務,無論這個任務是在下載中、暫停、完成還是其他任何狀態,都可以直接移除這個任務,他有一個重載方法,接受一個boolen參數,true表示刪除任務的時候同時刪除文件,false表示只刪除任務,但是文件保留在手機上。不傳的話,默認為false,即不刪除文件。
    • restart():重新下載一個任務。重新下載會先刪除以前的任務,同時也會刪除文件,然后從頭開始重新下載該文件。

Request的構建詳細參考OkGo的用法,這里重點介紹DownloadTask的構建,這里面的方法一個個介紹:

  1. request():靜態方法創建DownloadTask對象,接受兩個參數,第一個參數是tag,表示當前任務的唯一標識,就像介紹中說的,所有下載任務按照tag區分,不同的任務必須使用不一樣的tag,否者斷點會發生錯亂,如果相同的下載url地址,如果使用不一樣的tag,也會認為是兩個下載任務,不同的下載url地址,如果使用相同的tag,也會認為是同一個任務,導致斷點錯亂。切記,切記!!
  2. priority():表示當前任務的下載優先級,他是一個int類型的值,只要在int的大小范圍內,數值越大,優先級越高,也就會優先下載。當然也可以不設置,默認優先級為0,當所有任務優先級都一樣的時候,就會按添加順序下載。
  3. floder():單獨指定當前下載任務的文件夾目錄,如果你是6.0以上的系統,記得下載的時候先自己獲取sd卡的運行時權限,否則文件夾創建不成功,無法下載。當然也可以不指定,默認下載路徑/storage/emulated/0/download
  4. fileName():手動指定下載的文件名,一般來說是不需要手動指定的,也建議不要自己指定,除非你明確知道你要下載的是什么,或者你想改成你自己的文件名。如果不指定,文件名將按照以下規則自動獲取,獲取規則與OkGo文件下載獲取規則一致,點擊這里查看
  5. extra():這個方法相當於數據庫的擴展字段,我們知道我們斷點下載是需要保存下載進度信息的,而我們這個框架是保存在數據庫中,數據庫的字段都是寫死的,如果用戶想在我們的下載數據庫中保存自己的數據就做不到了,所以我們這里提供了三個擴展字段,允許用戶保存自己想要的數據,如果不需要的話,也不用調用該方法。
  6. register():這是個注冊監聽的方法,我們既然要下載文件,那么我們肯定要知道下載的進度和狀態是吧,就在這里注冊我們需要的監聽,監聽可以注冊多個,同時生效,當狀態發生改變的時候,每個監聽都會收到通知。當然如果你只是想下載一個文件,不關心他的回調,那么你不用注冊任何回調。

 


免責聲明!

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



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