亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

android okhttp的基礎(chǔ)使用【入門推薦】

 更新時(shí)間:2017年01月10日 16:26:16   作者:byhieg  
本文主要總結(jié)了Android著名網(wǎng)絡(luò)框架-okhttp的基礎(chǔ)使用。具有一定的參考價(jià)值,下面跟著小編一起來看下吧

這篇文章主要總結(jié)Android著名網(wǎng)絡(luò)框架-okhttp的基礎(chǔ)使用,后續(xù)可能會(huì)有關(guān)于他的高級(jí)使用。

okhttp是什么

okhttp是Android端的一個(gè)Http客戶端,其基礎(chǔ)功能相當(dāng)于Android自帶的HttpURLConnection和Apache HTTP Client,但他卻比自帶的2個(gè)Http客戶端優(yōu)越很多,一者是寫法簡單,二者okhttp處理很多網(wǎng)絡(luò)復(fù)雜問題,如會(huì)從很多常用的連接問題中自動(dòng)恢復(fù)。如果您的服務(wù)器配置了多個(gè)IP地址,當(dāng)?shù)谝粋€(gè)IP連接失敗的時(shí)候,OkHttp會(huì)自動(dòng)嘗試下一個(gè)IP。OkHttp還處理了代理服務(wù)器問題和SSL握手失敗等等很多問題。關(guān)于第二者,這篇文章不討論。

okhttp的導(dǎo)入

Gradle導(dǎo)入

 compile 'com.squareup.okhttp3:okhttp:3.2.0'
 compile 'com.squareup.okio:okio:1.6.0'

okhttp基礎(chǔ)使用

這里我們主要介紹簡單的使用,介紹內(nèi)容如下

  1. get請(qǐng)求
  2. post請(qǐng)求,參數(shù)是鍵值對(duì)
  3. post請(qǐng)求,多種類型的body
  4. 文件下載
  5. 加入Gson

get請(qǐng)求

get請(qǐng)求分為同步get和異步get,兩者的區(qū)別主要get的方式是工作在另一個(gè)線程還是工作在本線程。請(qǐng)求的方式大同小異。

首先定義一個(gè)OkHttpClient對(duì)象,如下

private OkHttpClient client = new OkHttpClient();

然后構(gòu)建一個(gè)Request,構(gòu)建方式如下:

Request request = new Request.Builder().
url("http://www.baidu.com").
build();

這個(gè)是最簡單的request的構(gòu)建方式,當(dāng)然我們可以構(gòu)建的很復(fù)雜。

 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方法為請(qǐng)求增加請(qǐng)求頭部,注意使用header(name, value)可以設(shè)置唯一的name、value。如果已經(jīng)有值,舊的將被移除,然后添加新的。使用addHeader(name, value)可以添加多值(添加,不移除已有的)。

同步的get方法,通過client.newCall(request).execute()方法得到請(qǐng)求的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)); }

結(jié)果如下:

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

響應(yīng)報(bào)文的實(shí)體可以通過response.body().string()獲??;如果希望獲得返回的二進(jìn)制字節(jié)數(shù)組,則調(diào)用response.body().bytes();如果你想拿到返回的inputStream,則調(diào)用response.body().byteStream()。

異步的get請(qǐng)求得到的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í)行請(qǐng)求成功的代碼,onFailure方法中,執(zhí)行請(qǐng)求失敗的代碼,下面給一個(gè)完整的異步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);
      }
     }
    });
   }
  });
 }
}

其實(shí)按照官網(wǎng)說的,回調(diào)是發(fā)生在response 的headers準(zhǔn)備好就發(fā)生的,所以有時(shí)候請(qǐng)求response的實(shí)體部分會(huì)發(fā)生阻塞。

post請(qǐng)求——鍵值對(duì)為參數(shù)。

post請(qǐng)求和get請(qǐng)求除了在構(gòu)建request上面不同以外,在處理response上面都是一樣的,所以下面我們只討論一下post構(gòu)建request,當(dāng)然post也是支持同步post和異步post的,可以參考get方法。

在構(gòu)建post的request時(shí)候,首先用FormBody.Builder去構(gòu)建request的body部分,栗子如下,當(dāng)然這是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ù)鍵值對(duì)。得到要構(gòu)造的body后用

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

獲得請(qǐng)求的request,后面的操作就和get方法是一樣的,這里可以參考異步get的栗子,構(gòu)建一個(gè)post的request.下面的寫法原封不變。

post請(qǐng)求--多種類型的body

上文已經(jīng)說了post和get的用法主要在構(gòu)建不同的request上面,所以接下來我們主要討論的也是如何構(gòu)建request.

參考上面,我們首先要?jiǎng)?chuàng)建一個(gè)requestBody,我們可以用下面的方式去構(gòu)建,當(dāng)然這也是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)上傳一個(gè)File,最后一個(gè)參數(shù)是請(qǐng)求的實(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;
 }

由于我后臺(tái)能力比較渣,這里用一個(gè)官網(wǎng)的例子來實(shí)現(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();

當(dāng)然除了這個(gè)方法以外,調(diào)用如下方法也是可以的,我們可以利用name和filename自己構(gòu)造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);

后面的寫法和上面類似,這樣我們就實(shí)現(xiàn)了文件上傳的寫法。

文件下載

剛才我們上面已經(jīng)說了,希望獲得返回的二進(jìn)制字節(jié)數(shù)組,則調(diào)用response.body().bytes();如果你想拿到返回的inputStream,則調(diào)用response.body().byteStream()。換句話說,文件的下載可以簡單的通過get請(qǐng)求,得到相應(yīng)的response,在把他的實(shí)體轉(zhuǎn)換成二進(jìn)制流寫入文件,就是實(shí)現(xiàn)了文件的下載。主要的寫法就是文件的讀寫,跟OKHttp關(guān)系不大,當(dāng)然我們也可以用okio來實(shí)現(xiàn)文件的讀寫,這里水平有限就不介紹了。下面給一個(gè)簡單的例子。

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ù)對(duì)已經(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

接下來,我們討論一個(gè)很實(shí)際的問題,Android的網(wǎng)絡(luò)請(qǐng)求一般不會(huì)去請(qǐng)求一個(gè)網(wǎng)站的Html,更多的是請(qǐng)求后臺(tái)接口的Json文件,所以我們用Gson來處理json的解析。這一部分和前面就不同了,前面多數(shù)講的是如何構(gòu)建不同的request來得到response,而對(duì)響應(yīng)的結(jié)果,處理都是一致的。但這里主要的寫法就是用Gson去處理response,而request的構(gòu)建則根據(jù)上面介紹的方法去構(gòu)建,無需改變。

Gson的導(dǎo)入

compile 'com.google.code.gson:gson:2.6.2'

比如我們后臺(tái)給出的api是這樣一個(gè)json文件

{
 "status": 0,
 "intro": "你好",
 "shopName": "byhieg", 
 "message": "查詢成功",
}

則我們可以簡單的構(gòu)建這樣的一個(gè)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對(duì)象。然后調(diào)用result對(duì)象的get方法就可以得到j(luò)son文件中的intro的值和shopname的值,以及status和message.這里就不多介紹了

Test result = new Gson().fromJson(response.body().string,Test.class);

總結(jié)

簡單介紹了okHttp的使用,對(duì)于一些高級(jí)用法請(qǐng)關(guān)注下篇文章,本人水平有限,如有錯(cuò)誤,還望指正。

以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!

相關(guān)文章

  • Android開發(fā)實(shí)現(xiàn)ListView部分布局監(jiān)聽的方法

    Android開發(fā)實(shí)現(xiàn)ListView部分布局監(jiān)聽的方法

    這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)ListView部分布局監(jiān)聽的方法,結(jié)合實(shí)例形式分析了Android通過設(shè)置tag標(biāo)志位實(shí)現(xiàn)ListView部分布局監(jiān)聽的相關(guān)操作技巧,需要的朋友可以參考下
    2018-01-01
  • Android安裝應(yīng)用 INSTALL_FAILED_DEXOPT 問題及解決辦法

    Android安裝應(yīng)用 INSTALL_FAILED_DEXOPT 問題及解決辦法

    這篇文章主要介紹了Android安裝應(yīng)用 INSTALL_FAILED_DEXOPT 解決辦法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Android自定義UI手勢(shì)密碼終結(jié)版

    Android自定義UI手勢(shì)密碼終結(jié)版

    這篇文章主要為大家詳細(xì)介紹了Android自定義UI手勢(shì)密碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Android開發(fā)之圖片壓縮實(shí)現(xiàn)方法分析

    Android開發(fā)之圖片壓縮實(shí)現(xiàn)方法分析

    這篇文章主要介紹了Android開發(fā)之圖片壓縮實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了Android圖片壓縮的原理、實(shí)現(xiàn)方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2019-03-03
  • Android消息機(jī)制原理深入分析

    Android消息機(jī)制原理深入分析

    這篇文章主要介紹了Android消息機(jī)制原理,Android的消息機(jī)制主要是指Handler的運(yùn)行機(jī)制以及Handler所附帶的MessageQueue和Looper的工作過程
    2022-12-12
  • Android中一種巧妙的drawable.xml替代方案分享

    Android中一種巧妙的drawable.xml替代方案分享

    這篇文章主要給大家介紹了關(guān)于Android中一種巧妙的drawable.xml替代方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • 通俗易通講解Android藍(lán)牙鍵值適配

    通俗易通講解Android藍(lán)牙鍵值適配

    這篇文章介紹了Android藍(lán)牙鍵值適配的方法,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值。需要的朋友可以收藏下,方便下次瀏覽觀看
    2021-12-12
  • Android studio設(shè)計(jì)簡易計(jì)算器

    Android studio設(shè)計(jì)簡易計(jì)算器

    這篇文章主要為大家詳細(xì)介紹了Android studio設(shè)計(jì)簡易計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • Andriod 自定義控件之音頻條

    Andriod 自定義控件之音頻條

    這篇文章主要介紹了Andriod 自定義控件之音頻條的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-11-11
  • Android 游戲開發(fā)入門簡單示例

    Android 游戲開發(fā)入門簡單示例

    本文主要介紹Android 游戲開發(fā),這里整理了詳細(xì)的開發(fā)游戲的資料,并提供簡單的游戲示例代碼,有興趣的同學(xué)可以參考下
    2016-08-08

最新評(píng)論