OKHttp的使用學(xué)習(xí)

? ? ? ?最近實際項目需要處理網(wǎng)絡(luò)請求(一般是個app都會有的),于是接觸了okhttp,目前也就剛剛會使用的程度,不過還是總結(jié)一下吧,個人學(xué)習(xí)的理解不喜勿噴哈。

? ? ? ?介紹就不多說了,它就是一個Android用來請求網(wǎng)絡(luò)的第三方類庫,開源的,是目前非?;鸬囊豢钶p量級HTTP框架,由Square公司開發(fā)。

? ? ? ? 好了廢話少說,下面直接上使用說明,我使用的是OKHttp3,就以O(shè)KHttp3為例子,因為是提取出來的單獨demo,可能有的變量類名沒有完全修改對,可能有名字不對的低級錯誤歡迎指正。

導(dǎo)入方法

在gradle里導(dǎo)入就行了

dependencies里添加這一行完成導(dǎo)入

implementation 'com.squareup.okhttp3:okhttp:3.10.0'

GET方法

同步:

public void getOkHttpByExeCute(final String url){

? ? ? ? new Thread(new Runnable() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void run() {

? ? ? ? ? ? ? ? try {

? ? ? ? ? ? ? ? ? ? //創(chuàng)建OkHttpClient實例

? ? ? ? ? ? ? ? ? ? OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS)

? ? ? ? ? ? ? ? ? ? ? ? ? ? .writeTimeout(20, TimeUnit.SECONDS).readTimeout(20, TimeUnit.SECONDS)

? ? ? ? ? ? ? ? ? ? ? ? ? ? .build();

? ? ? ? ? ? ? ? ? ? //創(chuàng)建Request

? ? ? ? ? ? ? ? ? ? Request request = new Request.Builder().url(url).build();

? ? ? ? ? ? ? ? ? ? Call call = okHttpClient.newCall(request);

? ? ? ? ? ? ? ? ? ? //獲取Response響應(yīng)

? ? ? ? ? ? ? ? ? ? final Response response = call.execute();

? ? ? ? ? ? ? ? ? ? if (response.isSuccessful()) {

? ? ? ? ? ? ? ? ? ? ? ? //UI操作在回到主線程執(zhí)行

? ? ? ? ? ? ? ? ? ? ? ? runOnUiThread(new Runnable() {

? ? ? ? ? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? ? ? ? ? public void run() {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(mContext,response.code() + response.message() + "",Toast.LENGTH_SHORT).show();

? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? });

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }catch (Exception e) {

? ? ? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? });

? ? }

異步:

異步請求不需要開啟新線程,只需要將回調(diào)在子線程中執(zhí)行

public void getOkHttpByEnqueue(final String url,final Context context){

try {

//創(chuàng)建OkHttpClient實例

? ? ? ? OkHttpClient okHttpClient =new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS)

.writeTimeout(20, TimeUnit.SECONDS).readTimeout(20, TimeUnit.SECONDS)

.build();

? ? ? ? //創(chuàng)建Request

? ? ? ? Request request =new Request.Builder().url(url).build();

? ? ? ? Call call = okHttpClient.newCall(request);

? ? ? ? //回調(diào)

? ? ? ? call.enqueue(new Callback() {

@Override

? ? ? ? ? ? public void onFailure(Call call, IOException e) {

}

@Override

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

if(response.isSuccessful()){

//本部分在子線程執(zhí)行

//UI操作在回到主線程執(zhí)行

? ? ? ? ? ? ? ? ? ? final Response response2 = response;

? ? ? ? ? ? ? ? ? ? runOnUiThread(new Runnable() {

@Override

? ? ? ? ? ? ? ? ? ? ? ? public void run() {

Toast.makeText(context,response2.code() +response2.message() +"",Toast.LENGTH_SHORT).show();

? ? ? ? ? ? ? ? ? ? ? ? }

});

? ? ? ? ? ? ? ? }

}

});

? ? }catch (Exception e) {

e.printStackTrace();

? ? }

}

POST方法

post鍵值對

//post異步請求發(fā)送鍵值對

public static void PostMapByEnqueue (String url, Map map, Callback callback,final Context context) {

FormBody.Builder builder =new FormBody.Builder();

? ? //遍歷集合

? ? for (String key : map.keySet()) {

builder.add(key, map.get(key));

? ? }

//創(chuàng)建Request

? ? Request request =new Request.Builder().url(url).post(builder.build()).build();

? ? Call call =getOkHttpClient().newCall(request);

? ? call.enqueue(new Callback() {

@Override

? ? ? ? public void onFailure(Call call, IOException e) {

}

@Override

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

if(response.isSuccessful()){

//子線程執(zhí)行

//UI操作在回到主線程執(zhí)行

? ? ? ? ? ? ? ? final Response response2 = response;

? ? ? ? ? ? ? ? runOnUiThread(new Runnable() {

@Override

? ? ? ? ? ? ? ? ? ? public void run() {

Toast.makeText(context,response2.code() +response2.message() +"",Toast.LENGTH_SHORT).show();

? ? ? ? ? ? ? ? ? ? }

});

? ? ? ? ? ? }

}

});

}

post JSON數(shù)據(jù)

//post異步請求發(fā)送json數(shù)據(jù)

public static void PostJson(String url, String string, Callback callback,final Context context) {

MediaType JSON = MediaType.parse("application/json; charset=utf-8");//數(shù)據(jù)類型為json格式,

? ? RequestBody body = RequestBody.create(JSON, string);

? ? //創(chuàng)建Request

? ? Request request =new Request.Builder().url(url).post(body).build();

? ? Call call =getOkHttpClient().newCall(request);

? ? call.enqueue(new Callback() {

@Override

? ? ? ? public void onFailure(Call call, IOException e) {

}

@Override

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

if(response.isSuccessful()){

//子線程執(zhí)行

//UI操作在回到主線程執(zhí)行

? ? ? ? ? ? ? ? final Response response2 = response;

? ? ? ? ? ? ? ?runOnUiThread(new Runnable() {

@Override

? ? ? ? ? ? ? ? ? ? public void run() {

Toast.makeText(context,response2.code() +response2.message() +"",Toast.LENGTH_SHORT).show();

? ? ? ? ? ? ? ? ? ? }

});

? ? ? ? ? ? }

}

});

}

okhttp實現(xiàn)下載功能

這一步在回調(diào)Callback中執(zhí)行,原理理解同上,將onResponse中的子線程操作具體為下載就行了,下載功能原理是從Response中獲取輸入流對象實現(xiàn)文件下載

//Okhttp實現(xiàn)下載功能(json數(shù)據(jù)同理)

public static void download(String url, Map map, Callback callback, final Context context, final String pathStr) {

FormBody.Builder builder =new FormBody.Builder();

? ? //遍歷集合

? ? for (String key : map.keySet()) {

builder.add(key, map.get(key));

? ? }

//創(chuàng)建Request

? ? Request request =new Request.Builder().url(url).post(builder.build()).build();

? ? Call call =getOkHttpClient().newCall(request);

? ? call.enqueue(new Callback() {

@Override

? ? ? ? public void onFailure(Call call, IOException e) {

}

@Override

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

if(response.isSuccessful()){

//子線程執(zhí)行

? ? ? ? ? ? ? ? try{

InputStream? is = response.body().byteStream();// 在Response中獲取輸入流對象

? ? ? ? ? ? ? ? ? ? File dir =new File(pathStr);

? ? ? ? ? ? ? ? ? ? if (!dir.exists()){

dir.mkdirs();

? ? ? ? ? ? ? ? ? ? }

File file =new File(dir, pathStr);

? ? ? ? ? ? ? ? ? ? FileOutputStream? fos =new FileOutputStream(file);

? ? ? ? ? ? ? ? ? ? byte[] buf =new byte[1024*8];

? ? ? ? ? ? ? ? ? ? int len =0;

? ? ? ? ? ? ? ? ? ? while ((len = is.read(buf)) != -1){

fos.write(buf, 0, len);

? ? ? ? ? ? ? ? ? ? }

fos.flush();//file下載完成

? ? ? ? ? ? ? ? }catch (Exception e) {

e.printStackTrace();

? ? ? ? ? ? ? ? }

}

}

});

}

進(jìn)一步的封裝

實際開發(fā)中,肯定一堆不同的地方要用到網(wǎng)絡(luò)請求,我們不可能每一次都寫一個post,get請求。為了進(jìn)一步方便使用,可以考慮封裝成一個工具類,我的思路如下:

首先定義獲取的數(shù)據(jù)類,ResponseResult

public class ResponseResult {

private int status;

? ? private Stringmsg;

? ? private Objectdata;

? ? public ResponseResult(int status, String msg, Object data) {

this.status = status;

? ? ? ? this.msg = msg;

? ? ? ? this.data = data;

? ? }

public ResponseResult() {

}

public int getStatus() {

return status;

? ? }

public void setStatus(int status) {

this.status = status;

? ? }

public StringgetMsg() {

return msg;

? ? }

public void setMsg(String msg) {

this.msg = msg;

? ? }

public ObjectgetData() {

return data;

? ? }

public void setData(Object data) {

this.data = data;

? ? }

}

然后自定義回調(diào)類,ResponseCallBack

在這里為了更好轉(zhuǎn)換返回的json數(shù)據(jù),我們需要導(dǎo)入fastjson這個類庫,解析json非常方便實用,當(dāng)然這就又是另一部分內(nèi)容了,這里就一筆帶過不做詳細(xì)介紹。

導(dǎo)入方法:

gradle里加入這一行完成導(dǎo)入

implementation"com.alibaba:fastjson:1.2.47"

好的回來繼續(xù)寫ResponseCallBack回調(diào)

public abstract class ResponseCallBack Callback {

private Handlerhandler = HttpRequestHandler.getInstance().getHandler();

? ? //主線程處理

? ? public abstract void onUi(HttpResult result);

? ? //主線程處理

? ? public abstract void onFailed(Call call, IOException e);

? ? @Override

? ? public void onFailure(final Call call, final IOException e) {

handler.post(new Runnable() {

@Override

? ? ? ? ? ? public void run() {

onFailed(call, e);

? ? ? ? ? ? }

});

? ? }

@Override

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

final String result = response.body().string();

? ? ? ? handler.post(new Runnable() {

@Override

? ? ? ? ? ? public void run() {

onUi(JSON.parseObject(result, ResponseResult .class));

? ? ? ? ? ? }

});

? ? }

}

接下來寫重點,okhttp的工具類:OkHttpUtil

public class OkHttpUtil {

private static OkHttpUtil okHttpUtil =null;

? ? private OkHttpUtil() {

}

public static OkHttpUtil?getInstance() {

if (okHttpUtil ==null) {

//加同步安全

? ? ? ? ? ? synchronized (OkHttpUtil.class) {

if (okHttpUtil ==null) {

okHttpUtil =new OkHttpUtil();

? ? ? ? ? ? ? ? }

}

}

return okHttpUtil;

? ? }

private static OkHttpClient okHttpClient =null;

? ? public synchronized static OkHttpClient getOkHttpClient() {

if (okHttpClient ==null) {

okHttpClient =new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS)

.writeTimeout(20, TimeUnit.SECONDS).readTimeout(20, TimeUnit.SECONDS)

.build();

? ? ? ? }

return okHttpClient;

? ? }

private static Handler mHandler =null;

? ? public synchronized static Handler getHandler() {

if (mHandler ==null) {

mHandler =new Handler();

? ? ? ? }

return mHandler;

? ? }

public static void doPost(String url, Map<String, String> map, Callback callback) {

FormBody.Builder builder =new FormBody.Builder();

? ? ? ? //遍歷集合

? ? ? ? for (String key : map.keySet()) {

builder.add(key, map.get(key));

? ? ? ? }

//創(chuàng)建Request

? ? ? ? Request request =new Request.Builder().url(url).post(builder.build()).build();

? ? ? ? Call call =getOkHttpClient().newCall(request);

? ? ? ? call.enqueue(callback);

? ? }

public static void doPost(String url, String string, Callback callback) {

MediaType JSON = MediaType.parse("application/json; charset=utf-8");//數(shù)據(jù)類型為json格式,

? ? ? ? RequestBody body = RequestBody.create(JSON, string);

? ? ? ? //創(chuàng)建Request

? ? ? ? Request request =new Request.Builder().url(url).post(body).build();

? ? ? ? Call call =getOkHttpClient().newCall(request);

? ? ? ? call.enqueue(callback);

? ? }

}

最后是使用,這里只舉post鍵值對的例子

private static int GET_OK = 0//獲取數(shù)據(jù)成功,實際數(shù)值根據(jù)項目定

public void getHttpData(String key,String value,String url){

final Map map =new HashMap();

? ? map.put(key, value);

? ? OkHttpUtil.getInstance().doPost(url, map, new ResponseCallBack() {

@Override

? ? ? ? public void onUi(ResponseResult result) {

if (result.getStatus() ==GET_OK) {

//主線程執(zhí)行操作

? ? ? ? ? ? }

}

@Override

? ? ? ? public void onFailed(Call call, IOException e) {

//主線程執(zhí)行操作

? ? ? ? }

});

}

封裝完成,收工~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,591評論 19 139
  • 項目要求用json提交參數(shù),以前在網(wǎng)上找的別的大神(忘了是誰)封裝的NetUtils工具不適應(yīng)了,在網(wǎng)上也沒找到適...
    微暖_440e閱讀 1,225評論 0 0
  • 自己備忘,隨便寫 android網(wǎng)絡(luò)框架源碼解析及對比 android常用網(wǎng)絡(luò)框架對比 Volley: 特點 基于...
    幻海流心閱讀 1,695評論 0 4
  • 一顆老樹 一支中性筆 一屋子的書 一處陌生的地方 一群不相識的人 一心一意 一人一生
    丿鋒芒閱讀 142評論 0 0
  • 藍(lán)裳怎比赤衣襟,背景爭如南海深。 偶現(xiàn)神情驚四座,孰知影響勝千金。 可憐無力施援手,始信無情非本心。 阮籍善為青白...
    隨意郝學(xué)敏閱讀 225評論 0 2

友情鏈接更多精彩內(nèi)容