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:
- 建立okHttpClient的物件。我們可直接new出來 也可以通過OkHttpClient.Builder()構建。
- 建立Request物件。
- 封裝成一個請求的任務Call
- 執行任務 call.execute();是同步請求直接返回Response但需要在子執行緒中執行。call.enqueue()時非同步請求。內部一個執行的回撥。
Post:
- 建立okHttpClient的物件。我們可直接new出來 也可以通過OkHttpClient.Builder()構建。
- 建立RequestBody
- 建立Request物件。
- 封裝成一個請求的任務Call
- 執行任務 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());
}
}
}
相關推薦
Android中OkHttp基礎用法
目前Android中的網路請求最主要的就是UrlConnection和OkHttp了。而UrlConnection聽說在安卓4.4以後也在內部實現了OkHttp。網路上OkHttp的封裝框架也挺多比如鴻羊大神的okhttputils。框架雖有很多,基礎我們更是需
詳細解讀-this-關鍵字在全局、函數、對象、jQuery中的基礎用法!
瀏覽器中 person ack true ++ 例子 span mar 編程 一、前言 1、 Javascript是一門基於對象的動態語言,也就是說,所有東西都是對象,一個很典型的例子就是函數也被視為普通的對象。Javascript可以通過一定的設計模式來實現面向對
Android中OkHttp使用(包括上傳與下載)
OkHttp介紹 OkHttp是Square公司的出品,一個Http請求庫,Google官方文件不推薦人們使用HttpClient,可是HttpURLConnection 實在是太難用了,因此很多人使用了OkHttp 來解決這問題, Andro
android中okhttp與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非常的方便簡單適用,實用性很強,用於實現某些特定的佈局,意義很重大.
Android中ListView的用法
(圖片跟內容一點關係也沒有[嘿哈]) 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
Android中Parcelable介面用法
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
Android中Okhttp和SPDY協議
HTTP的一個問題在於每個連線一次只允許一個請求和響應,這就讓瀏覽器或者其他客戶端為了並行請求必須生成多個套接字(socket)連線。對客戶端來說,這不算什麼大問題,但是對伺服器來說情況就不一樣了
Android中persistent屬性用法詳解
看見好的東西,不轉載真是罪過 本文例項講述了Android中persistent屬性用法。分享給大家供大家參考,具體如下: 前段時間在研究telephony時,一直沒有在framework下發現對telephony的初始化(PhoneFactory.Java中的make
android中Okhttp框架進行網路請求的工具類()
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;
android中selector的用法
1、目的: Android中的Selector主要是用來改變ListView和Button控制元件的預設背景。 2、目錄 res\drawable\search_select
android中color的用法及十六進位制編碼大全
在android開發中,適當的顏色搭配可以為我們的應用增色不少,廢話就不多了,下面是對 android開發中顏色使用的總結 顏色分類: 1.系統顏色 android內建的顏色,比如系統資源中定義的顏色,有以下幾個: BLACK(黑色),BLUE(藍