編輯:關於Android編程
okhttp已經被google認定為推薦的android請求框架,我們也可以在as中直接加入:
okhttp的依賴庫是:
compile 'com.squareup.okhttp:okhttp:2.5'
當然,作為eclipse的開發者來說,就不能使用依賴庫了。
我著重介紹okhttp的使用方法。
我們將okhttp所有的網絡請求方式都寫在RequestHandle類中。
需要注意的幾點是,
1,RequestHandle使用單例。因為okhttp使用單例來操作實例。
2,線程阻塞方式的請求需要在非ui線程中。
3,異步回調結果還處在非ui線程中,所以如果要更新ui,需要handler。
1,將RequestHandle寫成單例模式:
/**
* 單例請求網絡,只能傳入baseactivity
*/
private static volatile RequestHandle requestHandle = null;
public synchronized static RequestHandle getRequestInterface() {
if (requestHandle == null) {
synchronized (RequestHandle.class) {
if (requestHandle == null) {
requestHandle = new RequestHandle();
}
}
}
return requestHandle;
}
2,定義常量和初始化對象
//創建隊列,用於異步調用
private Request request;
//線程阻塞方式調用
private Response response;
//訪問對象
private Call call;
//okhttp實例
private OkHttpClient mOkHttpClient;
//線程阻塞方式請求的get,post狀態碼
private final static int GET_INSTANCE = 0;
private final static int POST_INSTANCE = 1;
//默認超時時間
private final static int VALUE_DEFAULT_TIME_OUT = 20 * 1000;
/**
* 參數類型
* "text", 文本
* "image", 圖片
* "audio",音頻
* "video",視頻
* "object",其他
*/
private static final MediaType MEDIA_TYPE_TEXT = MediaType.parse("text/x-markdown; charset=utf-8");
private static final MediaType MEDIA_TYPE_JPG = MediaType.parse("image/png");
private static final MediaType MEDIA_TYPE_AUDIO = MediaType.parse("audio/mp3");
private static final MediaType MEDIA_TYPE_VIDEO = MediaType.parse("video/mp4");
private static final MediaType MEDIA_TYPE_OBJECT = MediaType.parse("application/octet-stream");
private static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");
//給每個網絡請求的標記
public static final String TAG_DATA = "tag_data";
public static final String TAG_IMAGE = "tag_image";
public static final String TAG_FILE = "tag_file";
private RequestHandle() {
//創建okHttpClient對象
mOkHttpClient = new OkHttpClient();
mOkHttpClient.setConnectTimeout(VALUE_DEFAULT_TIME_OUT, TimeUnit.MILLISECONDS);//連接超時
mOkHttpClient.setReadTimeout(VALUE_DEFAULT_TIME_OUT, TimeUnit.MILLISECONDS);//讀取超時
mOkHttpClient.setWriteTimeout(VALUE_DEFAULT_TIME_OUT, TimeUnit.MILLISECONDS);//寫入超時
}
3,線程阻塞的請求,即非異步的。
get請求
/**
* 線程阻塞的單例發送get請求,線程阻塞的方式需要在非ui線程中
*/
public void sendGetRequestBlocking(String url) {
try {
//創建一個請求
request = new Request
.Builder()
.tag(TAG_DATA)
.url(url)
.build();
response = mOkHttpClient.newCall(request).execute();
callBackByEnqueueBlocking(response);
} catch (IOException e) {
e.printStackTrace();
return;
}
}
post請求:
/**
* 異步的post請求,線程阻塞的方式需要在非ui線程中
*
* @param url 請求地址
* @param builder 請求參數
*/
public void sendPostRequestBlocking(String url, MultipartBuilder builder) {
sendPostRequestBlocking(url, builder, null);
}
post上傳文件:
/**異步的post請求,線程阻塞的方式需要在非ui線程中,可以附帶文件
* @param url
* @param builder
* @param files
*/
public void sendPostRequestBlocking(String url, MultipartBuilder builder, File[] files) {
try {
//builder.addFormDataPart("參數", "值");
if (files != null && files.length != 0) {
//遍歷file數組,得到所有file文件
for (File file : files) {
builder.addFormDataPart("file", file.getName(), RequestBody.create(MEDIA_TYPE_OBJECT, file));
}
}
String tag = files == null ? TAG_DATA : TAG_FILE;
request = new Request.Builder()
.url(url)
.tag(tag)
.post(builder.build())
.build();
response = mOkHttpClient.newCall(request).execute();
callBackByEnqueueBlocking(response);
} catch (IOException e) {
e.printStackTrace();
}
}
線程阻塞請求的結果處理:
//隊列請求(線程阻塞)的結果處理方法
public void callBackByEnqueueBlocking(Response response) {
try {
//判斷是否是成功的
if (response.isSuccessful()) {
//成功
//String jsonStr=response.body().string();//字符串,無編碼
String jsonStr = new String(response.body().bytes(), "UTF-8");//二進制字節數組
//InputStream inputStream=response.body().byteStream();//輸入流
try {
JSONObject jsonObject = new JSONObject(jsonStr);
//解析數據處理
//發送數據處理
} catch (JSONException e) {
e.printStackTrace();
}
} else {
//失敗
response.code();//失敗碼
response.message();//失敗信息
}
} catch (IOException e) {
e.printStackTrace();
}
}
4,異步請求
get請求
/**
* 異步get請求
*
* @param url 請求的哪個接口,異步請求
*/
public void sendGetRequest(String url) {
//創建一個Request
request = new Request.Builder()
.url(url)
.tag(TAG_DATA)
.build();
call = mOkHttpClient.newCall(request);
callBackByEnqueue(call);
}
post請求
/**
* 異步的post請求
*/
public void sendPostRequest(String url, MultipartBuilder builder) {
sendPostRequest(url, builder, null);
}
post上傳文件
/** 異步的post請求,傳文件
* @param url
* @param builder
* @param files
*/
public void sendPostRequest(String url, MultipartBuilder builder, File[] files) {
//builder.addFormDataPart("參數", "值");
if (files != null && files.length != 0) {
//遍歷file數組,得到所有file文件
for (File file : files) {
builder.addFormDataPart("file", file.getName(), RequestBody.create(MEDIA_TYPE_OBJECT, file));
}
}
String tag = files == null ? TAG_DATA : TAG_FILE;
request = new Request.Builder()
.url(url)
.tag(tag)
.post(builder.build())
.build();
call = mOkHttpClient.newCall(request);
callBackByEnqueue(call);
}
異步請求結果回調處理:
//隊列請求(異步)的結果處理方法
public void callBackByEnqueue(Call call) {
//new call
call = mOkHttpClient.newCall(request);
//需要注意的是異步回調還是在子線程中,所以如果要更新ui,則記得handler
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
//失敗
}
@Override
public void onResponse(Response response) {
//響應
try {
if (response.isSuccessful()) {
//String jsonStr=response.body().string();//字符串,無編碼
String jsonStr = null;//二進制字節數組
jsonStr = new String(response.body().bytes(), "UTF-8");
//InputStream inputStream=response.body().byteStream();//輸入流
try {
JSONObject jsonObject = new JSONObject(jsonStr);
//解析數據處理
//發送數據處理
} catch (JSONException e) {
e.printStackTrace();
}
} else {
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
5,設置超時
/**
* 設置超時
*
* @param value
*/
public void setTimeOut(int value) {
if (mOkHttpClient == null) return;
mOkHttpClient.setConnectTimeout(value, TimeUnit.MILLISECONDS);//連接超時
mOkHttpClient.setReadTimeout(value, TimeUnit.MILLISECONDS);//讀取超時
mOkHttpClient.setWriteTimeout(value, TimeUnit.MILLISECONDS);//寫入超時
}
6,清除一個正在請求的操作
/**
* 取消一個當前正在處理的Call
* 使用Call.cancel()可以立即停止掉一個正在執行的call。
* 注意:如果一個線程正在寫請求或者讀響應,將會引發IOException。
*/
public void cancelByCall() {
if (call != null) {
try {
call.cancel();
} catch (Exception e) {
e.printStackTrace();
}
}
}
7,清除所有的請求
/**
* 清楚所有網絡請求
* 你可以通過tags來同時取消多個請求。
* 當你構建一請求時,使用RequestBuilder.tag(tag)來分配一個標簽。
* 之後你就可以用OkHttpClient.cancel(tag)來取消所有帶有這個tag的call。
*
* @param isCancelAllRequests
*/
public void cancelAllRequests(boolean isCancelAllRequests) {
if (mOkHttpClient != null) {
try {
if (isCancelAllRequests) {
mOkHttpClient.cancel(TAG_DATA);
mOkHttpClient.cancel(TAG_IMAGE);
mOkHttpClient.cancel(TAG_FILE);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
8,文件下載、上傳帶進度顯示
因為okhttp自身無法顯示下載進度,所以借用網上的代碼實現下載進度顯示。
下載進度回調
/**
* 非ui線程回調文件下載進度
* 這個是非ui線程回調,不可直接操作UI
*/
final ProgressListener progressResponseListener = new ProgressListener() {
@Override
public void onProgress(long bytesRead, long contentLength, boolean done) {
//長度未知的情況下回返回-1
if (contentLength != -1 && (100 * bytesRead) / contentLength >= 0) {
String donePercent = (100 * bytesRead) / contentLength + "%";//上傳進度
}
}
};
下載方法:
/**
* 下載文件
*
* @param url
*/
public void downloadFile(String url) {
request = new Request.Builder()
.url(url)
.build();
//包裝Response使其支持進度回調
ProgressHelper.addProgressResponseListener(mOkHttpClient, progressResponseListener)
.newCall(request)
.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
String message;
if (!NetWorkUtil.isNetworkConnected(UIAppliaction.getInstance())) {
//判斷是否是因為沒有網絡的原因
message = "網絡不給給力";
} else {
message = e.getMessage();
}
}
@Override
public void onResponse(Response response) throws IOException {
String message = "";
String url = response.request().url().getPath();
//獲得url地址的文件後綴名
String filename = url.substring(message.indexOf("."), message.length());
InputStream inputStream = response.body().byteStream();//輸入流
//通過流保存文件的工具類
if (FileUtil.insertSDCardFromInput("文件絕對路徑", filename, inputStream))
message = "下載完成";
else
message = "文件保存失敗";
}
});
}
至於其中回調的方法我這裡就只貼出代碼。因為是別人處理的代碼,我就分享下載地址。
http://pan.baidu.com/s/1i4GIJtz
ec32
代碼經測試回調進度是正常的。
這些就是基本的okhttp的使用。自己經過封裝後用起來也是非常方便的。這裡分享出來供大家學習。
一、eclipse 中生成android keystore 建立任意一個android項目(例如:AntForAndroid) Export Signed Appl
RatingBar簡單介紹RatingBar是基於SeekBar(拖動條)和ProgressBar(狀態條)的擴展,用星形來顯示等級評定,在使用默認RatingBar時,
支付寶支付在app項目中非常常見,現在把集成步驟提出了,雖然非常簡單,但是,希望對第一次集成支付的同學有幫助。要集成別人的東西,第一步當然是去看他的開發文檔,支付寶支付以
Notifications in Android 4.4 and Lower notification是很重要的部分,它與service,BroadcastReceive