標籤:
相關文章
Android網路編程(一)HTTP協議原理
Android網路編程(二)HttpClient與HttpURLConnection
Android網路編程(三)Volley用法全解析
Android網路編程(四)從源碼解析volley
Android網路編程(五)OkHttp2.x用法全解析
前言
上一篇介紹了OkHttp2.x的用法,這一篇文章我們來對照OkHttp2.x版本來看看,OkHttp3使用起來有那些變化。當然,看這篇文章前建議看一下前一篇文章Android網路編程(五)OkHttp2.x用法全解析。
1.使用前準備
Android Studio 配置gradle:
compile ‘com.squareup.okhttp3:okhttp:3.2.0‘ compile ‘com.squareup.okio:okio:1.7.0‘
添加網路許可權:
<uses-permission android:name="android.permission.INTERNET"/>
2.非同步GET請求
慣例,請求百度:
private void getAsynHttp() { mOkHttpClient=new OkHttpClient(); Request.Builder requestBuilder = new Request.Builder().url("http://www.baidu.com"); //可以省略,預設是GET請求 requestBuilder.method("GET",null); Request request = requestBuilder.build(); Call mcall= mOkHttpClient.newCall(request); mcall.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { if (null != response.cacheResponse()) { String str = response.cacheResponse().toString(); Log.i("wangshu", "cache---" + str); } else { response.body().string(); String str = response.networkResponse().toString(); Log.i("wangshu", "network---" + str); } runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), "請求成功", Toast.LENGTH_SHORT).show(); } }); } }); }
與2.x版本並沒有什麼不同,比較鬱悶的是回調仍然不在UI線程。
2.非同步POST請求
OkHttp3非同步POST請求和OkHttp2.x有一些差別就是沒有FormEncodingBuilder這個類,替代它的是功能更加強大的FormBody:
private void postAsynHttp() { mOkHttpClient=new OkHttpClient(); RequestBody formBody = new FormBody.Builder() .add("size", "10") .build(); Request request = new Request.Builder() .url("http://api.1-blog.com/biz/bizserver/article/list.do") .post(formBody) .build(); Call call = mOkHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { String str = response.body().string(); Log.i("wangshu", str); runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), "請求成功", Toast.LENGTH_SHORT).show(); } }); } }); }
3.非同步上傳檔案
上傳檔案本身也是一個POST請求,上一篇沒有講,這裡我們補上。首先定義上傳檔案類型:
public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");
將sdcard根目錄的wangshu.txt檔案上傳到伺服器上:
private void postAsynFile() { mOkHttpClient=new OkHttpClient(); File file = new File("/sdcard/wangshu.txt"); Request request = new Request.Builder() .url("https://api.github.com/markdown/raw") .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file)) .build(); mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { Log.i("wangshu",response.body().string()); } }); }
當然如果想要改為同步的上傳檔案只要調用 mOkHttpClient.newCall(request).execute()就可以了。
在wangshu.txt檔案中有一行字“Android網路編程(六)OkHttp3用法全解析”我們運行程式點擊傳送檔案按鈕,最終請求網路返回的結果就是我們txt檔案中的內容 :
當然不要忘了添加如下許可權:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
4.非同步下載檔案
下載檔案同樣在上一篇沒有講到,實現起來比較簡單,在這裡下載一張圖片,我們得到Response後將流寫進我們指定的圖片檔案中就可以了。
private void downAsynFile() { mOkHttpClient = new OkHttpClient(); String url = "http://img.my.csdn.net/uploads/201603/26/1458988468_5804.jpg"; Request request = new Request.Builder().url(url).build(); mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) { InputStream inputStream = response.body().byteStream(); FileOutputStream fileOutputStream = null; try { fileOutputStream = new FileOutputStream(new File("/sdcard/wangshu.jpg")); byte[] buffer = new byte[2048]; int len = 0; while ((len = inputStream.read(buffer)) != -1) { fileOutputStream.write(buffer, 0, len); } fileOutputStream.flush(); } catch (IOException e) { Log.i("wangshu", "IOException"); e.printStackTrace(); } Log.d("wangshu", "檔案下載成功"); } }); }
5.非同步上傳Multipart檔案
這種情境很常用,我們有時會上傳檔案同時還需要傳其他類型的欄位,OkHttp3實現起來很簡單,需要注意的是沒有伺服器接收我這個Multipart檔案,所以這裡只是舉個例子,具體的應用還要結合實際工作中對應的伺服器。
首先定義上傳檔案類型:
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
private void sendMultipart(){ mOkHttpClient = new OkHttpClient(); RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("title", "wangshu") .addFormDataPart("image", "wangshu.jpg", RequestBody.create(MEDIA_TYPE_PNG, new File("/sdcard/wangshu.jpg"))) .build(); Request request = new Request.Builder() .header("Authorization", "Client-ID " + "...") .url("https://api.imgur.com/3/image") .post(requestBody) .build(); mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { Log.i("wangshu", response.body().string()); } });}
6.設定逾時時間和緩衝
和OkHttp2.x有區別的是不能通過OkHttpClient直接設定逾時時間和緩衝了,而是通過OkHttpClient.Builder來設定,通過builder配置好OkHttpClient後用builder.build()來返回OkHttpClient,所以我們通常不會調用new OkHttpClient()來得到OkHttpClient,而是通過builder.build():
File sdcache = getExternalCacheDir(); int cacheSize = 10 * 1024 * 1024; OkHttpClient.Builder builder = new OkHttpClient.Builder() .connectTimeout(15, TimeUnit.SECONDS) .writeTimeout(20, TimeUnit.SECONDS) .readTimeout(20, TimeUnit.SECONDS) .cache(new Cache(sdcache.getAbsoluteFile(), cacheSize)); OkHttpClient mOkHttpClient=builder.build();
7.關於取消請求和封裝
取消請求仍舊可以調用call.cancel(),這個沒有變化,不明白的可以查看上一篇文章Android網路編程(五)OkHttp2.x用法全解析,這裡就不贅述了,封裝上一篇也講過仍舊推薦OkHttpFinal,它目前是基於OkHttp3來進行封裝的。
8.關於源碼Demo
源碼Demo很簡單就四個按鈕用來測試上面講到的內容:
github源碼下載
Android網路編程(六)OkHttp3用法全解析