android okhttp的基礎使用【入門推薦】
這篇文章主要總結Android著名網(wǎng)絡框架-okhttp的基礎使用,后續(xù)可能會有關于他的高級使用。
okhttp是什么
okhttp是Android端的一個Http客戶端,其基礎功能相當于Android自帶的HttpURLConnection和Apache HTTP Client,但他卻比自帶的2個Http客戶端優(yōu)越很多,一者是寫法簡單,二者okhttp處理很多網(wǎng)絡復雜問題,如會從很多常用的連接問題中自動恢復。如果您的服務器配置了多個IP地址,當?shù)谝粋€IP連接失敗的時候,OkHttp會自動嘗試下一個IP。OkHttp還處理了代理服務器問題和SSL握手失敗等等很多問題。關于第二者,這篇文章不討論。
okhttp的導入
Gradle導入
compile 'com.squareup.okhttp3:okhttp:3.2.0' compile 'com.squareup.okio:okio:1.6.0'
okhttp基礎使用
這里我們主要介紹簡單的使用,介紹內(nèi)容如下
- get請求
- post請求,參數(shù)是鍵值對
- post請求,多種類型的body
- 文件下載
- 加入Gson
get請求
get請求分為同步get和異步get,兩者的區(qū)別主要get的方式是工作在另一個線程還是工作在本線程。請求的方式大同小異。
首先定義一個OkHttpClient對象,如下
private OkHttpClient client = new OkHttpClient();
然后構建一個Request,構建方式如下:
Request request = new Request.Builder(). url("http://www.baidu.com"). build();
這個是最簡單的request的構建方式,當然我們可以構建的很復雜。
Request request = new Request.Builder(). url("http://www.baidu.com"). addHeader("User-Agent","android"). header("Content-Type","text/html; charset=utf-8"). build();
通過addHeader和header方法為請求增加請求頭部,注意使用header(name, value)可以設置唯一的name、value。如果已經(jīng)有值,舊的將被移除,然后添加新的。使用addHeader(name, value)可以添加多值(添加,不移除已有的)。
同步的get方法,通過client.newCall(request).execute()方法得到請求的response.
Response response = okHttpClient.newCall(request).execute();
OkHttp封裝了很多處理response的方法,比如response.headers()的得到headers.
Headers headers = response.headers(); for (int i = 0; i < headers.size(); i++) { System.out.println(headers.name(i) + ": " + headers.value(i)); }
結果如下:
Date: Mon, 18 Apr 2016 05:23:43 GMT Content-Type: text/html; charset=utf-8 Transfer-Encoding: chunked Connection: Keep-Alive Vary: Accept-Encoding Set-Cookie: BAIDUID=A323EC9BF678C0EB78E20741FD71211B:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com Set-Cookie: BIDUPSID=A323EC9BF678C0EB78E20741FD71211B; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com Set-Cookie: PSTM=1460957023; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com Set-Cookie: BDSVRTM=0; path=/ Set-Cookie: BD_HOME=0; path=/ Set-Cookie: H_PS_PSSID=1434_19672_18281_19690_17948_18205_19558_15952_12257; path=/; domain=.baidu.com P3P: CP=" OTI DSP COR IVA OUR IND COM " Cache-Control: private Cxy_all: baidu+2db7793e0e32b9f6c20be8f623e1ae43 Expires: Mon, 18 Apr 2016 05:22:55 GMT X-Powered-By: HPHP Server: BWS/1.1 X-UA-Compatible: IE=Edge,chrome=1 BDPAGETYPE: 1 BDQID: 0xfacc6fc10004ca96 BDUSERID: 0 OkHttp-Sent-Millis: 1460957021226 OkHttp-Received-Millis: 1460957021430
響應報文的實體可以通過response.body().string()獲取;如果希望獲得返回的二進制字節(jié)數(shù)組,則調(diào)用response.body().bytes();如果你想拿到返回的inputStream,則調(diào)用response.body().byteStream()。
異步的get請求得到的response方法是通過如下方法
okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { } });
在onResponse方法中,執(zhí)行請求成功的代碼,onFailure方法中,執(zhí)行請求失敗的代碼,下面給一個完整的異步get的栗子
import android.os.Bundle; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.text.method.ScrollingMovementMethod; import android.widget.TextView; import java.io.IOException; import okhttp3.Call; import okhttp3.Callback; import okhttp3.Headers; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public class MainActivity extends AppCompatActivity { private OkHttpClient okHttpClient = new OkHttpClient(); public TextView show; public Handler handler = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); show = (TextView) findViewById(R.id.show); show.setMovementMethod(ScrollingMovementMethod.getInstance()); Request request = new Request.Builder(). url("http://www.baidu.com"). addHeader("User-Agent", "android"). header("Content-Type", "text/html; charset=utf-8"). get(). build(); okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, final Response response) throws IOException { final Headers headers = response.headers(); final String str = response.body().string(); handler.post(new Runnable() { @Override public void run() { for (int i = 0; i < headers.size(); i++) { show.append(headers.name(i) + ": " + headers.value(i)); show.append(str); } } }); } }); } }
其實按照官網(wǎng)說的,回調(diào)是發(fā)生在response 的headers準備好就發(fā)生的,所以有時候請求response的實體部分會發(fā)生阻塞。
post請求——鍵值對為參數(shù)。
post請求和get請求除了在構建request上面不同以外,在處理response上面都是一樣的,所以下面我們只討論一下post構建request,當然post也是支持同步post和異步post的,可以參考get方法。
在構建post的request時候,首先用FormBody.Builder去構建request的body部分,栗子如下,當然這是OKHttp3的方法.
FormBody.Builder builder = new FormBody.Builder(); for(int i = 0 ; i < key.size() ;i ++){ builder.add(key.get(i),value.get(i)); } RequestBody body = builder.build();
builder中add的是要加入的參數(shù)鍵值對。得到要構造的body后用
Request request = new Request.Builder().url(url).post(body).build();
獲得請求的request,后面的操作就和get方法是一樣的,這里可以參考異步get的栗子,構建一個post的request.下面的寫法原封不變。
post請求--多種類型的body
上文已經(jīng)說了post和get的用法主要在構建不同的request上面,所以接下來我們主要討論的也是如何構建request.
參考上面,我們首先要創(chuàng)建一個requestBody,我們可以用下面的方式去構建,當然這也是okhttp3的方法
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
已表單上傳的形式去提交post。我們看一下builder的方法
/** Add a part to the body. */ public Builder addPart(RequestBody body) { return addPart(Part.create(body)); } /** Add a part to the body. */ public Builder addPart(Headers headers, RequestBody body) { return addPart(Part.create(headers, body)); } /** Add a form data part to the body. */ public Builder addFormDataPart(String name, String value) { return addPart(Part.createFormData(name, value)); } /** Add a form data part to the body. */ public Builder addFormDataPart(String name, String filename, RequestBody body) { return addPart(Part.createFormData(name, filename, body)); }
從這里我們可以看出可以直接用 public Builder addFormDataPart(String name, String filename, RequestBody body)上傳一個File,最后一個參數(shù)是請求的實體,可以通過 RequestBody.create(final MediaType contentType, final File file) 獲得,而MediaType則可以通過下面方法獲得
//調(diào)用judgeType方法 private static final MediaType MEDIA_TYPE = MediaType.parse(judgeType(fileName); //judge方法如下 private String judgeType(String path) { FileNameMap fileNameMap = URLConnection.getFileNameMap(); String contentTypeFor = fileNameMap.getContentTypeFor(path); if (contentTypeFor == null) { contentTypeFor = "application/octet-stream"; } return contentTypeFor; }
由于我后臺能力比較渣,這里用一個官網(wǎng)的例子來實現(xiàn)一遍我剛才討論的方法。
MultipartBody.Builder builder = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("image", "logo-square.png", RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png"))); RequestBody requestBody = builder.build(); Request request = new Request.Builder() .header("Authorization", "Client-ID " +"9199fdef135c122") .url("https://api.imgur.com/3/image") .post(requestBody) .build();
當然除了這個方法以外,調(diào)用如下方法也是可以的,我們可以利用name和filename自己構造Header傳上去。
public Builder addPart(Headers headers, RequestBody body) { return addPart(Part.create(headers, body))
栗子如下:
builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + name + "\"; filename=\"" + fileName + "\""),fileBody);
后面的寫法和上面類似,這樣我們就實現(xiàn)了文件上傳的寫法。
文件下載
剛才我們上面已經(jīng)說了,希望獲得返回的二進制字節(jié)數(shù)組,則調(diào)用response.body().bytes();如果你想拿到返回的inputStream,則調(diào)用response.body().byteStream()。換句話說,文件的下載可以簡單的通過get請求,得到相應的response,在把他的實體轉(zhuǎn)換成二進制流寫入文件,就是實現(xiàn)了文件的下載。主要的寫法就是文件的讀寫,跟OKHttp關系不大,當然我們也可以用okio來實現(xiàn)文件的讀寫,這里水平有限就不介紹了。下面給一個簡單的例子。
private void _download(final String url, final String destFileDir, final ResultCallback callback) { final Request request = new Request.Builder().url(url).build(); final Call call = okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { InputStream is = null; byte[] buf = new byte[2048]; int len = 0; FileOutputStream fos = null; try { is = response.body().byteStream(); File file = new File(destFileDir, getFileName(url)); fos = new FileOutputStream(file); while((len = is.read(buf)) != -1){ fos.write(buf,0,len); } fos.flush(); //....省略后續(xù)對已經(jīng)保存的文件的操作 } catch (IOException e) { e.printStackTrace(); }finally { try { if (is != null) is.close(); } catch (IOException e) { } try { if (fos != null) fos.close(); } catch (IOException e) { } } } }); }
加入Gson
接下來,我們討論一個很實際的問題,Android的網(wǎng)絡請求一般不會去請求一個網(wǎng)站的Html,更多的是請求后臺接口的Json文件,所以我們用Gson來處理json的解析。這一部分和前面就不同了,前面多數(shù)講的是如何構建不同的request來得到response,而對響應的結果,處理都是一致的。但這里主要的寫法就是用Gson去處理response,而request的構建則根據(jù)上面介紹的方法去構建,無需改變。
Gson的導入
compile 'com.google.code.gson:gson:2.6.2'
比如我們后臺給出的api是這樣一個json文件
{ "status": 0, "intro": "你好", "shopName": "byhieg", "message": "查詢成功", }
則我們可以簡單的構建這樣的一個Test.java文件,如下所示:
public class Test { /** * status : 0 * intro : byhieg * shopName : byhige * message : 查詢成功 */ private int status; private String intro; private String shopName; private String message; public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public String getIntro() { return intro; } public void setIntro(String intro) { this.intro = intro; } public String getShopName() { return shopName; } public void setShopName(String shopName) { this.shopName = shopName; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
在獲得到response之后,用如下代碼把Json文件解析成result對象。然后調(diào)用result對象的get方法就可以得到json文件中的intro的值和shopname的值,以及status和message.這里就不多介紹了
Test result = new Gson().fromJson(response.body().string,Test.class);
總結
簡單介紹了okHttp的使用,對于一些高級用法請關注下篇文章,本人水平有限,如有錯誤,還望指正。
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!
- Android第三方HTTP網(wǎng)絡支持包OkHttp的基礎使用教程
- Android使用okHttp(get方式)下載圖片
- 詳解Android中使用OkHttp發(fā)送HTTP的post請求的方法
- Android中Retrofit+OkHttp進行HTTP網(wǎng)絡編程的使用指南
- Android M(6.x)使用OkHttp包解析和發(fā)送JSON請求的教程
- 使用Android的OkHttp包實現(xiàn)基于HTTP協(xié)議的文件上傳下載
- Android的HTTP擴展包OkHttp中的緩存功能使用方法解析
- Android App開發(fā)中HTTP擴展包OkHttp的入門使用指南
- Android中使用OkHttp包處理HTTP的get和post請求的方法
- Android中的Retrofit+OkHttp+RxJava緩存架構使用
相關文章
Android開發(fā)實現(xiàn)ListView部分布局監(jiān)聽的方法
這篇文章主要介紹了Android開發(fā)實現(xiàn)ListView部分布局監(jiān)聽的方法,結合實例形式分析了Android通過設置tag標志位實現(xiàn)ListView部分布局監(jiān)聽的相關操作技巧,需要的朋友可以參考下2018-01-01Android安裝應用 INSTALL_FAILED_DEXOPT 問題及解決辦法
這篇文章主要介紹了Android安裝應用 INSTALL_FAILED_DEXOPT 解決辦法,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04Android開發(fā)之圖片壓縮實現(xiàn)方法分析
這篇文章主要介紹了Android開發(fā)之圖片壓縮實現(xiàn)方法,結合實例形式分析了Android圖片壓縮的原理、實現(xiàn)方法及相關操作注意事項,需要的朋友可以參考下2019-03-03Android中一種巧妙的drawable.xml替代方案分享
這篇文章主要給大家介紹了關于Android中一種巧妙的drawable.xml替代方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2018-09-09