1. 程式人生 > >Android中OkHttp基礎用法

Android中OkHttp基礎用法

目前Android中的網路請求最主要的就是UrlConnection和OkHttp了。而UrlConnection聽說在安卓4.4以後也在內部實現了OkHttp。網路上OkHttp的封裝框架也挺多比如鴻羊大神的okhttputils。框架雖有很多,基礎我們更是需要了解的 ,看他們都是封裝的啥內容。首先先從其最基本的用法開始

OkHttp的用法步驟:
引入最新的gradle依賴

    compile 'com.squareup.okhttp3:okhttp:3.5.0'
    compile 'com.squareup.okio:okio:1.11.0'

Get:

  1. 建立okHttpClient的物件。我們可直接new出來 也可以通過OkHttpClient.Builder()構建。
  2. 建立Request物件。
  3. 封裝成一個請求的任務Call
  4. 執行任務 call.execute();是同步請求直接返回Response但需要在子執行緒中執行。call.enqueue()時非同步請求。內部一個執行的回撥。

Post:

  1. 建立okHttpClient的物件。我們可直接new出來 也可以通過OkHttpClient.Builder()構建。
  2. 建立RequestBody
  3. 建立Request物件。
  4. 封裝成一個請求的任務Call
  5. 執行任務 call.execute();是同步請求直接返回Response但需要在子執行緒中執行。call.enqueue()時非同步請求。內部一個執行的回撥。

示例程式碼:(官方文件)

package com.chs.okhttpdemo;

import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;

import
okhttp3.Call; import okhttp3.Callback; import okhttp3.FormBody; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import okio.BufferedSink; public class MainActivity extends AppCompatActivity { public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8"); private static final MediaType MEDIA_TYPE_JPG = MediaType.parse("application/octet-stream"); OkHttpClient okHttpClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //1.拿到OkHttpClient物件 okHttpClient = new OkHttpClient.Builder(). connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .build(); } public void doGet(View view) { //建立request物件 Request.Builder builder = new Request.Builder(); Request request = builder.get().url("http://192.168.1.63:8080/album/login?name=chs&password=123").build(); execute(request); } //post提交(表單)鍵值對 public void doPost(View view) { //拿到body的構建器 FormBody.Builder builder = new FormBody.Builder(); //新增引數 builder.add("name", "chs") .add("password", "123"); //拿到requestBody RequestBody requestBody = builder.build(); //建立request物件 Request request = new Request.Builder() .url("http://192.168.1.63:8080/album/login") .post(requestBody) .build(); execute(request); } //post提交String 這個API最好不要傳送大於1M的字串 public void doPostString(View view) { String postBody = "{name:chs,pwd:123}"; //建立requestBody RequestBody requestBody = RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody); //建立request Request request = new Request.Builder() .url("http://192.168.1.63:8080/album/login") .post(requestBody) .build(); execute(request); } //post提交流 public void doPostStream(View view) { RequestBody requestBody = new RequestBody() { @Override public MediaType contentType() { return MEDIA_TYPE_MARKDOWN; } @Override public void writeTo(BufferedSink sink) throws IOException { sink.writeUtf8("doPostStream\n"); sink.writeUtf8("{name:doPostStream,title:doPostStream}"); } }; Request request = new Request.Builder() .url("http://192.168.1.63:8080/album/login") .post(requestBody) .build(); execute(request); } //post提交File public void doPostFile(View view) { //圖片在手機上的路徑 String path = Environment.getExternalStorageDirectory().getPath()+"/BXT_SetPic/20170118/1484724630838.jpg"; LogUtil.i("path:"+path); File file = new File(path); //建立requestBody RequestBody requestBody = RequestBody.create(MEDIA_TYPE_MARKDOWN, file); Request request = new Request.Builder() .url("http://192.168.1.63:8080/album/login") .post(requestBody) .build(); execute(request); } //post提交Multipart 鍵值對和file一起提交 public void doPostMultipart(View view) { //圖片在手機上的路徑 String path = Environment.getExternalStorageDirectory().getPath()+"/BXT_SetPic/20170118/1484724630838.jpg"; LogUtil.i("pth:"+path); File file = new File(path); RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("name", "Square") .addFormDataPart("password", "1111") .addFormDataPart("image", "1484724630838.jpg", RequestBody.create(MEDIA_TYPE_JPG, file)) .build(); //封裝一層來獲取上傳的進度 CountingRequestBody countRequestBody = new CountingRequestBody(requestBody, new CountingRequestBody.OnProgressListener() { @Override public void OnProgress(long byteWrite, long contentLength) { LogUtil.i(byteWrite+"/"+contentLength); } }); Request request = new Request.Builder() .url("http://192.168.1.63:8080/album/login") .post(countRequestBody) .build(); execute(request); } //下載 public void doDownLoad(View view) { //建立request物件 Request.Builder builder = new Request.Builder(); Request request = builder.get().url("http://192.168.1.63:8080/album//files/album.jpg").build(); //封裝成一個請求的任務 Call call = okHttpClient.newCall(request); //同步的請求 Response response = call.execute(); // 執行請求(非同步的請求) call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { LogUtil.i("請求失敗:" + e.toString()); } @Override public void onResponse(Call call, Response response) throws IOException { LogUtil.i("請求成功:"); //總的長度 long totalLength = response.body().contentLength(); //下載的進度 long sum = 0; InputStream is = response.body().byteStream(); int len = 0; byte [] buff = new byte[1024]; File file = new File(Environment.getExternalStorageDirectory(),"album.jpg"); FileOutputStream os = new FileOutputStream(file); while ((len=is.read(buff))!=-1){ os.write(buff,0,len); sum+=len; LogUtil.i(sum+"/"+totalLength); } os.flush();; os.close(); is.close(); LogUtil.i("success"); } }); } private void execute(Request request) { //封裝成一個請求的任務 Call call = okHttpClient.newCall(request); //同步的請求 Response response = call.execute(); // 執行請求(非同步的請求) call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { LogUtil.i("請求失敗:" + e.toString()); } @Override public void onResponse(Call call, Response response) throws IOException { LogUtil.i("請求成功:" + response.body().string()); } }); } }

因為RequestBody沒有提供上傳的進度,所以在上傳的時候包裝RequestBody用來計算上傳的進度

package com.chs.okhttpdemo;

import java.io.IOException;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;

/**
 * 作者:chs on 2017/1/19 16:05
 * 郵箱:[email protected]
 * 包裝RequestBody用來計算上傳的進度
 */

public class ProgressRequestBody extends RequestBody {
    //真正的mRequestBody
    private RequestBody mRequestBody;
    //上傳回調介面
    private OnProgressListener mProgressListener;

    public ProgressRequestBody(RequestBody requestBody, OnProgressListener progressListener) {
        mRequestBody = requestBody;
        mProgressListener = progressListener;
    }

    public interface OnProgressListener {
        void OnProgress(long byteWrite,long contentLength);
    }
    @Override
    public MediaType contentType() {
        return mRequestBody.contentType();
    }

    @Override
    public long contentLength() {
        try {
            return mRequestBody.contentLength();
        } catch (IOException e) {
            return -1;
        }
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        CountingSink countingSink = new CountingSink(sink);
        BufferedSink bufferedSink = Okio.buffer(countingSink);
        mRequestBody.writeTo(bufferedSink);
        bufferedSink.flush();
    }

    protected final class CountingSink extends ForwardingSink{
        private long byteWrite;
        public CountingSink(Sink delegate) {
            super(delegate);
        }

        @Override
        public void write(Buffer source, long byteCount) throws IOException {
            super.write(source, byteCount);
            byteWrite+=byteCount;
            mProgressListener.OnProgress(byteWrite,contentLength());
        }
    }
}

相關推薦

AndroidOkHttp基礎用法

目前Android中的網路請求最主要的就是UrlConnection和OkHttp了。而UrlConnection聽說在安卓4.4以後也在內部實現了OkHttp。網路上OkHttp的封裝框架也挺多比如鴻羊大神的okhttputils。框架雖有很多,基礎我們更是需

詳細解讀-this-關鍵字在全局、函數、對象、jQuery基礎用法

瀏覽器中 person ack true ++ 例子 span mar 編程 一、前言 1、 Javascript是一門基於對象的動態語言,也就是說,所有東西都是對象,一個很典型的例子就是函數也被視為普通的對象。Javascript可以通過一定的設計模式來實現面向對

AndroidOkHttp使用(包括上傳與下載)

OkHttp介紹 OkHttp是Square公司的出品,一個Http請求庫,Google官方文件不推薦人們使用HttpClient,可是HttpURLConnection 實在是太難用了,因此很多人使用了OkHttp 來解決這問題, Andro

androidokhttp與webview的cookie共享

轉載請註明出處:https://blog.csdn.net/u011038298/article/details/84551136   1.在WebView中同步cookie import android.os.Build; import android.text.Text

移動開發----android uri.parse()用法

android 中uri.parse()用法 //1,調web瀏覽器 Uri myBlogUri = Uri.parse("http://xxxxx.com"); returnIt = new Intent(Intent.ACTION_VIEW, myBlogUri); //2,地圖 U

Android Data Binding基礎用法

功能簡介 匯入DataBinding 使用DataBinding 定義entity 修改Layout檔案 實現databinding

Android RecyclerView的用法(一)

RecyclerView 許可權 implementation 'com.android.support:recyclerview-v7:28.0.0' 首先RecyclerView非常的方便簡單適用,實用性很強,用於實現某些特定的佈局,意義很重大.

AndroidListView的用法

(圖片跟內容一點關係也沒有[嘿哈])   l  ListView的作用: (1)    將資料填充到佈局 (2)    處理使用者的選擇點選操作 l  建立ListView需要的3個元素: (1)&nbs

c++sort基礎用法

用法一:陣列排序            對一個數組進行升序排序 #include <algorithm> #include <iostream> #include <cstdio> using namespace std; int m

Android基礎

比起java類庫的慘不忍睹,android的類庫可以說很對的起觀眾了,下面是具體的類庫: 1、Android.util 核心使用包(看名字就知道啦),包括了低階類,例如,專用的容器、字串格式化和XML解析程式。 2、Android.os 作業系統包,提供了基本作業系統服務

Android基礎----在按鈕上顯示影象的方式

Button: 方法一:使用android:drawable^^^(^^^表示Left、Top、Right或Bottom)屬性將影象顯示在文字的周圍(上下左右)。 示例: <Button android:id="@+id/button1" and

AndroidParcelable介面用法

public class Book implements Parcelable { private String bookName; private String author; private int publishDate; public Book() {

golang一些基礎用法

range類似迭代器操作,返回 (索引, 值) 或 (鍵, 值)。其可以使用的物件包括string,array/slice,map,channel。其中string,array/slice返回的第一個value都是index,第二個value表示值;map返回第一個元素為k

AndroidOkhttp和SPDY協議

  HTTP的一個問題在於每個連線一次只允許一個請求和響應,這就讓瀏覽器或者其他客戶端為了並行請求必須生成多個套接字(socket)連線。對客戶端來說,這不算什麼大問題,但是對伺服器來說情況就不一樣了

Androidpersistent屬性用法詳解

看見好的東西,不轉載真是罪過 本文例項講述了Android中persistent屬性用法。分享給大家供大家參考,具體如下: 前段時間在研究telephony時,一直沒有在framework下發現對telephony的初始化(PhoneFactory.Java中的make

androidOkhttp框架進行網路請求的工具類()

package com.example.utils; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Iterat

Android基礎----如何獲得LinearLayout佈局的高和寬

存在兩種情況: 1)由於LinearLayout是View的子類,因此可以使用View.getMeasuredWidth和View.getMeasuredHeight方法來獲取元件的寬度和高度。 View view =getLayoutInflater().inflate

android okhttp post請求傳遞json資料

public final static int CONNECT_TIMEOUT = 60; public final static int READ_TIMEOUT = 100;

androidselector的用法

1、目的:        Android中的Selector主要是用來改變ListView和Button控制元件的預設背景。 2、目錄       res\drawable\search_select

androidcolor的用法及十六進位制編碼大全

在android開發中,適當的顏色搭配可以為我們的應用增色不少,廢話就不多了,下面是對 android開發中顏色使用的總結 顏色分類: 1.系統顏色 android內建的顏色,比如系統資源中定義的顏色,有以下幾個: BLACK(黑色),BLUE(藍