android OkHttp學習以及使用例子
- 博客分類:
- android
</div>
1. GET
在OKHttp,每次網絡請求就是一個Request,我們在Request裏填寫我們需要的url,header等其他參數,再通過Request構造出Call,Call內部去請求參數,得到回覆,並將結果告訴調用者。
- package com.jackchan.test.okhttptest;
- import android.os.Bundle;
- import android.support.v7.app.ActionBarActivity;
- import android.util.Log;
- import com.squareup.okhttp.Cache;
- import com.squareup.okhttp.Callback;
- import com.squareup.okhttp.OkHttpClient;
- import com.squareup.okhttp.Request;
- import com.squareup.okhttp.Response;
- import java.io.File;
- import java.io.IOException;
- public class TestActivity extends ActionBarActivity {
- private final static String TAG = “TestActivity”;
- private final OkHttpClient client = new OkHttpClient();
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_test);
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- execute();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- }
- public void execute() throws Exception {
- Request request = new Request.Builder()
- .url(”http://publicobject.com/helloworld.txt”)
- .build();
- Response response = client.newCall(request).execute();
- if(response.isSuccessful()){
- System.out.println(response.code());
- System.out.println(response.body().string());
- }
- }
- }
package com.jackchan.test.okhttptest;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import com.squareup.okhttp.Cache;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import java.io.File;
import java.io.IOException;
public class TestActivity extends ActionBarActivity {
private final static String TAG = "TestActivity";
private final OkHttpClient client = new OkHttpClient();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
new Thread(new Runnable() {
@Override
public void run() {
try {
execute();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
public void execute() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
Response response = client.newCall(request).execute();
if(response.isSuccessful()){
System.out.println(response.code());
System.out.println(response.body().string());
}
}
}
我們通過Request.Builder傳入url,然後直接execute執行得到Response,通過Response可以得到code,message等信息。
這個是通過同步的方式去操作網絡請求,而android本身是不允許在UI線程做網絡請求操作的,因此我們需要自己開啓一個線程。
當然,OKHttp也支持異步線程並且有回調返回,有了上面同步的基礎,異步只要稍加改動即可。
- private void enqueue(){
- Request request = new Request.Builder()
- .url(”http://publicobject.com/helloworld.txt”)
- .build();
- client.newCall(request).enqueue(new Callback() {
- @Override
- public void onFailure(Request request, IOException e) {
- }
- // 成功時響應的回調函數
- @Override
- public void onResponse(Response response) throws IOException {
- //NOT UI Thread
- if(response.isSuccessful()){
- System.out.println(response.code());
- System.out.println(response.body().string());
- }
- }
- });
- }
private void enqueue(){
Request request = new Request.Builder()
.url(“http://publicobject.com/helloworld.txt“)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
}
// 成功時響應的回調函數
@Override
public void onResponse(Response response) throws IOException {
//NOT UI Thread
if(response.isSuccessful()){
System.out.println(response.code());
System.out.println(response.body().string());
}
}
});
}
就是在同步的基礎上講execute改成enqueue,並且傳入回調接口,但接口回調回來的代碼是在非UI線程的,因此如果有更新UI的操作記得用Handler或者其他方式。
2、POST
說完GET該介紹些如何使用POST,POST情況下我們一般需要傳入參數,甚至一些header,傳入參數或者header
比如傳入header
- Request request = new Request.Builder()
- .url(”https://api.github.com/repos/square/okhttp/issues”)
- .header(”User-Agent”, “OkHttp Headers.java”)
- .addHeader(”Accept”, “application/json; q=0.5”)
- .addHeader(”Accept”, “application/vnd.github.v3+json”)
- .build();
Request request = new Request.Builder()
.url("https://api.github.com/repos/square/okhttp/issues")
.header("User-Agent", "OkHttp Headers.java")
.addHeader("Accept", "application/json; q=0.5")
.addHeader("Accept", "application/vnd.github.v3+json")
.build();
傳入POST參數
- RequestBody formBody = new FormEncodingBuilder()
- .add(”platform”, “android”)
- .add(”name”, “bug”)
- .add(”subject”, “XXXXXXXXXXXXXXX”)
- .build();
- Request request = new Request.Builder()
- .url(url)
- .post(body)
- .build();
RequestBody formBody = new FormEncodingBuilder()
.add(“platform”, “android”)
.add(“name”, “bug”)
.add(“subject”, “XXXXXXXXXXXXXXX”)
.build();
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
可以看出來,傳入header或者post參數都是傳到Request裏面,因此最後的調用方式也和GET方式一樣
- Response response = client.newCall(request).execute();
- if (response.isSuccessful()) {
- return response.body().string();
- } else {
- throw new IOException(“Unexpected code ” + response);
- }
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
} else {
throw new IOException("Unexpected code " + response);
}
這個代碼是同步網絡請求,異步就改成enqueue就行了。
請求緩存
在網絡請求中,緩存技術是一項應用比較廣泛的技術,需要對請求過的網絡資源進行緩存,而okhttp也支持這一技術,也使用十分方便,前文中經常出現的OkHttpClient這個時候就要派送用場了。看下面代碼
- package com.jackchan.test.okhttptest;
- import android.os.Bundle;
- import android.support.v7.app.ActionBarActivity;
- import android.util.Log;
- import com.squareup.okhttp.Cache;
- import com.squareup.okhttp.CacheControl;
- import com.squareup.okhttp.Call;
- import com.squareup.okhttp.Callback;
- import com.squareup.okhttp.OkHttpClient;
- import com.squareup.okhttp.Request;
- import com.squareup.okhttp.Response;
- import java.io.File;
- import java.io.IOException;
- public class TestActivity extends ActionBarActivity {
- private final static String TAG = “TestActivity”;
- // 請求資源客戶端
- private final OkHttpClient client = new OkHttpClient();
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_test);
- File sdcache = getExternalCacheDir();
- int cacheSize = 10 1024 1024; // 10 MiB
- // 對資源進行緩存
- client.setCache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
- // 開啓一個線程
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- execute();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- }
- public void execute() throws Exception {
- Request request = new Request.Builder()
- .url(”http://publicobject.com/helloworld.txt”)
- .build();
- Response response1 = client.newCall(request).execute();
- if (!response1.isSuccessful()) throw new IOException(“Unexpected code ” + response1);
- String response1Body = response1.body().string();
- System.out.println(”Response 1 response: ” + response1);
- System.out.println(”Response 1 cache response: ” + response1.cacheResponse());
- System.out.println(”Response 1 network response: ” + response1.networkResponse());
- Response response2 = client.newCall(request).execute();
- if (!response2.isSuccessful()) throw new IOException(“Unexpected code ” + response2);
- String response2Body = response2.body().string();
- System.out.println(”Response 2 response: ” + response2);
- System.out.println(”Response 2 cache response: ” + response2.cacheResponse());
- System.out.println(”Response 2 network response: ” + response2.networkResponse());
- System.out.println(”Response 2 equals Response 1? ” + response1Body.equals(response2Body));
- }
- }
package com.jackchan.test.okhttptest;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import com.squareup.okhttp.Cache;
import com.squareup.okhttp.CacheControl;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import java.io.File;
import java.io.IOException;
public class TestActivity extends ActionBarActivity {
private final static String TAG = "TestActivity";
// 請求資源客戶端
private final OkHttpClient client = new OkHttpClient();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
File sdcache = getExternalCacheDir();
int cacheSize = 10 * 1024 * 1024; // 10 MiB
// 對資源進行緩存
client.setCache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
// 開啓一個線程
new Thread(new Runnable() {
@Override
public void run() {
try {
execute();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
public void execute() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
Response response1 = client.newCall(request).execute();
if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response1);
String response1Body = response1.body().string();
System.out.println("Response 1 response: " + response1);
System.out.println("Response 1 cache response: " + response1.cacheResponse());
System.out.println("Response 1 network response: " + response1.networkResponse());
Response response2 = client.newCall(request).execute();
if (!response2.isSuccessful()) throw new IOException("Unexpected code " + response2);
String response2Body = response2.body().string();
System.out.println("Response 2 response: " + response2);
System.out.println("Response 2 cache response: " + response2.cacheResponse());
System.out.println("Response 2 network response: " + response2.networkResponse());
System.out.println("Response 2 equals Response 1? " + response1Body.equals(response2Body));
}
}
okhttpclient有點像Application的概念,統籌着整個okhttp的大功能,通過它設置緩存目錄。
response1 的結果在networkresponse,代表是從網絡請求加載過來的,而response2的networkresponse 就爲null,而cacheresponse有數據,因爲我設置了緩存因此第二次請求時發現緩存裏有就不再去走網絡請求了。
但有時候即使在有緩存的情況下我們依然需要去後臺請求最新的資源(比如資源更新了)這個時候可以使用強制走網絡來要求必須請求網絡數據
- public void execute() throws Exception {
- Request request = new Request.Builder()
- .url(”http://publicobject.com/helloworld.txt”)
- .build();
- Response response1 = client.newCall(request).execute();
- if (!response1.isSuccessful()) throw new IOException(“Unexpected code ” + response1);
- String response1Body = response1.body().string();
- System.out.println(”Response 1 response: ” + response1);
- System.out.println(”Response 1 cache response: ” + response1.cacheResponse());
- System.out.println(”Response 1 network response: ” + response1.networkResponse());
- request = request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK).build();
- Response response2 = client.newCall(request).execute();
- if (!response2.isSuccessful()) throw new IOException(“Unexpected code ” + response2);
- String response2Body = response2.body().string();
- System.out.println(”Response 2 response: ” + response2);
- System.out.println(”Response 2 cache response: ” + response2.cacheResponse());
- System.out.println(”Response 2 network response: ” + response2.networkResponse());
- System.out.println(”Response 2 equals Response 1? ” + response1Body.equals(response2Body));
- }
public void execute() throws Exception {
Request request = new Request.Builder()
.url(“http://publicobject.com/helloworld.txt“)
.build();
Response response1 = client.newCall(request).execute();
if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response1);
String response1Body = response1.body().string();
System.out.println("Response 1 response: " + response1);
System.out.println("Response 1 cache response: " + response1.cacheResponse());
System.out.println("Response 1 network response: " + response1.networkResponse());
request = request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK).build();
Response response2 = client.newCall(request).execute();
if (!response2.isSuccessful()) throw new IOException("Unexpected code " + response2);
String response2Body = response2.body().string();
System.out.println("Response 2 response: " + response2);
System.out.println("Response 2 cache response: " + response2.cacheResponse());
System.out.println("Response 2 network response: " + response2.networkResponse());
System.out.println("Response 2 equals Response 1? " + response1Body.equals(response2Body));
}
上面的代碼中
response2對應的request變成
- request = request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK).build();
request = request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK).build();
取消操作
網絡操作中,經常會使用到對請求的cancel操作,okhttp的也提供了這方面的接口,call的cancel操作。使用Call.cancel()可以立即停止掉一個正在執行的call。如果一個線程正在寫請求或者讀響應,將會引發IOException,同時可以通過Request.Builder.tag(Object tag)給請求設置一個標籤,並使用OkHttpClient.cancel(Object tag)來取消所有帶有這個tag的call。但如果該請求已經在做讀寫操作的時候,cancel是無法成功的,會拋出IOException異常。
- public void canceltest() throws Exception {
- Request request = new Request.Builder()
- .url(”http://httpbin.org/delay/2”) // This URL is served with a 2 second delay.
- .build();
- final long startNanos = System.nanoTime();
- final Call call = client.newCall(request);
- // Schedule a job to cancel the call in 1 second.
- executor.schedule(new Runnable() {
- @Override
- public void run() {
- System.out.printf(”%.2f Canceling call.%n”, (System.nanoTime() - startNanos) / 1e9f);
- call.cancel();
- System.out.printf(”%.2f Canceled call.%n”, (System.nanoTime() - startNanos) / 1e9f);
- }
- }, 1, TimeUnit.SECONDS);
- try {
- System.out.printf(”%.2f Executing call.%n”, (System.nanoTime() - startNanos) / 1e9f);
- Response response = call.execute();
- System.out.printf(”call is cancel:” + call.isCanceled() + “%n”);
- System.out.printf(”%.2f Call was expected to fail, but completed: %s%n”,
- (System.nanoTime() - startNanos) / 1e9f, response);
- } catch (IOException e) {
- System.out.printf(”%.2f Call failed as expected: %s%n”,
- (System.nanoTime() - startNanos) / 1e9f, e);
- }
- }
public void canceltest() throws Exception {
Request request = new Request.Builder()
.url(“http://httpbin.org/delay/2“) // This URL is served with a 2 second delay.
.build();
final long startNanos = System.nanoTime();
final Call call = client.newCall(request);
// Schedule a job to cancel the call in 1 second.
executor.schedule(new Runnable() {
@Override
public void run() {
System.out.printf("%.2f Canceling call.%n", (System.nanoTime() - startNanos) / 1e9f);
call.cancel();
System.out.printf("%.2f Canceled call.%n", (System.nanoTime() - startNanos) / 1e9f);
}
}, 1, TimeUnit.SECONDS);
try {
System.out.printf("%.2f Executing call.%n", (System.nanoTime() - startNanos) / 1e9f);
Response response = call.execute();
System.out.printf("call is cancel:" + call.isCanceled() + "%n");
System.out.printf("%.2f Call was expected to fail, but completed: %s%n",
(System.nanoTime() - startNanos) / 1e9f, response);
} catch (IOException e) {
System.out.printf("%.2f Call failed as expected: %s%n",
(System.nanoTime() - startNanos) / 1e9f, e);
}
}
轉自:http://blog.csdn.net/chenzujie/article/details/46994073
- package com.test.okhttp;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.List;
- import java.util.concurrent.TimeUnit;
- import org.apache.http.client.utils.URLEncodedUtils;
- import org.apache.http.message.BasicNameValuePair;
- import com.squareup.okhttp.Call;
- import com.squareup.okhttp.Callback;
- import com.squareup.okhttp.OkHttpClient;
- import com.squareup.okhttp.Request;
- import com.squareup.okhttp.Response;
- public class OkHttpClientManager {
- private static final OkHttpClient mOkHttpClient = new OkHttpClient();
- static {
- mOkHttpClient.setConnectTimeout(30, TimeUnit.SECONDS);
- }
- /
- 該方法不會開啓異步線程。
- @param request
- @return
- @throws IOException
- /
- public static Response execute(Request request) throws IOException {
- return mOkHttpClient.newCall(request).execute();
- }
- /
- 開啓異步線程訪問網絡
- @param request
- @param responseCallback
- /
- public static void enqueue(Request request, Callback responseCallback) {
- mOkHttpClient.newCall(request).enqueue(responseCallback);
- }
- /
- 開啓異步線程訪問網絡, 且不在意返回結果(實現空callback)
- @param request
- /
- public static void enqueue(Request request) {
- mOkHttpClient.newCall(request).enqueue(new Callback() {
- @Override
- public void onResponse(Response arg0) throws IOException {
- }
- @Override
- public void onFailure(Request arg0, IOException arg1) {
- }
- });
- }
- public static String getStringFromServer(String url) throws IOException {
- Request request = new Request.Builder().url(url).build();
- Response response = execute(request);
- if (response.isSuccessful()) {
- String responseUrl = response.body().string();
- return responseUrl;
- } else {
- throw new IOException(“Unexpected code ” + response);
- }
- }
- private static final String CHARSET_NAME = “UTF-8”;
- /
- 這裏使用了HttpClinet的API。只是爲了方便
- @param params
- @return
- /
- public static String formatParams(List<BasicNameValuePair> params) {
- return URLEncodedUtils.format(params, CHARSET_NAME);
- }
- /
- 爲HttpGet 的 url 方便的添加多個name value 參數。
- @param url
- @param params
- @return
- /
- public static String attachHttpGetParams(String url,
- List<BasicNameValuePair> params) {
- return url + “?” + formatParams(params);
- }
- /
- 爲HttpGet 的 url 方便的添加1個name value 參數。
- @param url
- @param name
- @param value
- @return
- /
- public static String attachHttpGetParam(String url, String name,
- String value) {
- return url + “?” + name + “=” + value;
- }
- /*
- 下載內容
- @param url
- @param destFileDir
- */
- public static void downloadAsyn(final String url, final String destFileDir) {
- final Request request = new Request.Builder().url(url).build();
- final Call call = mOkHttpClient.newCall(request);
- call.enqueue(new Callback() {
- @Override
- public void onFailure(final Request request, final IOException e) {
- }
- @Override
- public void onResponse(Response response) {
- System.out.println(”Download……….”);
- 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();
- } catch (IOException e) {
- } finally {
- try {
- if (is != null)
- is.close();
- } catch (IOException e) {
- }
- try {
- if (fos != null)
- fos.close();
- } catch (IOException e) {
- }
- }
- }
- });
- }
- private static String getFileName(String path) {
- int separatorIndex = path.lastIndexOf(“/”);
- return (separatorIndex < 0) ? path : path.substring(separatorIndex + 1,
- path.length());
- }
- }
package com.test.okhttp;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
public class OkHttpClientManager {
private static final OkHttpClient mOkHttpClient = new OkHttpClient();
static {
mOkHttpClient.setConnectTimeout(30, TimeUnit.SECONDS);
}
/**
*
* 該方法不會開啓異步線程。
*
* @param request
*
* @return
*
* @throws IOException
*/
public static Response execute(Request request) throws IOException {
return mOkHttpClient.newCall(request).execute();
}
/**
*
* 開啓異步線程訪問網絡
*
* @param request
*
* @param responseCallback
*/
public static void enqueue(Request request, Callback responseCallback) {
mOkHttpClient.newCall(request).enqueue(responseCallback);
}
/**
*
* 開啓異步線程訪問網絡, 且不在意返回結果(實現空callback)
*
* @param request
*/
public static void enqueue(Request request) {
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(Response arg0) throws IOException {
}
@Override
public void onFailure(Request arg0, IOException arg1) {
}
});
}
public static String getStringFromServer(String url) throws IOException {
Request request = new Request.Builder().url(url).build();
Response response = execute(request);
if (response.isSuccessful()) {
String responseUrl = response.body().string();
return responseUrl;
} else {
throw new IOException("Unexpected code " + response);
}
}
private static final String CHARSET_NAME = "UTF-8";
/**
*
* 這裏使用了HttpClinet的API。只是爲了方便
*
* @param params
*
* @return
*/
public static String formatParams(List<BasicNameValuePair> params) {
return URLEncodedUtils.format(params, CHARSET_NAME);
}
/**
*
* 爲HttpGet 的 url 方便的添加多個name value 參數。
*
* @param url
*
* @param params
*
* @return
*/
public static String attachHttpGetParams(String url,
List<BasicNameValuePair> params) {
return url + "?" + formatParams(params);
}
/**
*
* 爲HttpGet 的 url 方便的添加1個name value 參數。
*
* @param url
*
* @param name
*
* @param value
*
* @return
*/
public static String attachHttpGetParam(String url, String name,
String value) {
return url + "?" + name + "=" + value;
}
/**
* 下載內容
* @param url
* @param destFileDir
*/
public static void downloadAsyn(final String url, final String destFileDir) {
final Request request = new Request.Builder().url(url).build();
final Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(final Request request, final IOException e) {
}
@Override
public void onResponse(Response response) {
System.out.println("Download..........");
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();
} catch (IOException e) {
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
}
try {
if (fos != null)
fos.close();
} catch (IOException e) {
}
}
}
});
}
private static String getFileName(String path) {
int separatorIndex = path.lastIndexOf("/");
return (separatorIndex < 0) ? path : path.substring(separatorIndex + 1,
path.length());
}
}
參考:http://blog.csdn.net/lmj623565791/article/details/47911083