編輯:關於Android編程
此篇博客,我們通過2種方式來了解下okhttp的文件上傳至服務器
ps一下,還有一種就是添加params參數,生成post提交時的分塊request(這裡就不列出實例效果了,但是封裝代碼博文後附加)
同步上傳
異步上傳
還有一種就是添加params參數,生成post提交時的分塊request
在說明同步、異步上傳代碼前,我們先來了解下上傳圖片文件的大概思路:
我這裡貼出一個截圖,就很簡單明了了,截圖如下:

截圖的意思就是將圖片壓縮成byte[]字節數組,然後通過Base64.encodeToString(bitmap2Bytes, Base64.DEFAULT)將字節數組,轉為64位的字符串,然後在封裝請求體,傳給服務器即可
了解完上傳圖片文件的大概思路後, 我們來看下我們代碼是如何實現的?
我公司請求是用的https,我這個例子,就沒有去https認證證書,我就直接https 不驗證證書方式(信任所有證書)
在SaflyApplication中進行如下代碼設置:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">
public static OkHttpClient getUnsafeOkHttpClient() {
try {
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
final javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(sslSocketFactory);
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
OkHttpClient okHttpClient = builder.connectTimeout(60, TimeUnit.SECONDS).writeTimeout(60, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).build();
return okHttpClient;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
樓上的代碼,也是我找的度娘搜索的,下面這段代碼就初始化了一個OkHttpClient對象,設置了連接時間,讀取時間等信息
OkHttpClient okHttpClient = builder.connectTimeout(60, TimeUnit.SECONDS).writeTimeout(60, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).build();
我們在OkHttpManger進行
private Handler okHttpHandler;
private OkHttpClient mOkHttpClient;
private OkHttpManger(){
this.mOkHttpClient = SaflyApplication.getInstance().getUnsafeOkHttpClient();
this.okHttpHandler = new Handler(Looper.getMainLooper());
}
public static final OkHttpManger getInstance(){
return SingleFactory.manger;
}
private static final class SingleFactory{
private static final OkHttpManger manger = new OkHttpManger();
}
構造一個單利模式,然後為了線程之間通訊,我們還初始化了一個handler,用來進行ui線程的頁面更新操作
我們先來看看同步上傳頭像代碼
Response response = OkHttpManger.getInstance().postSyncJson("https://10.0.5.48:7771/SetVPHUserInfo", Json);
public Response postSyncJson(String url, String json) throws IOException {
final RequestBody requestBody = RequestBody.create(JSON_TYPE, json);
final Request request = new Request.Builder().url(url).post(requestBody).build();
return mOkHttpClient.newCall(request).execute();
}
本例中我構造json字符串是用的JSONObject的方式,
如果對如何構建Json字符串還不是很明白的,可以看我如下的博客文章:
fastjson–Gson生成Json字符串,並且解析Json字符串生成對象
JsonObject生成Json字符串,並且解析為對象—–JsonReader解析Json字符串
另外還有一種方式,就是自定義拼接的方式(我公司就是用的這樣的方法,這裡就不贅述了)
針對本例的上傳服務端的json格式,我們用JSONObject如下方法即可生成所需要的json字符串
private String createJson() throws JSONException {
JSONObject jsonObject = new JSONObject();
JSONObject body = new JSONObject();
body.put("photo_type", "jpeg");
body.put("nickname", "hehe");
body.put("context", Base64.encodeToString(bitmap2Bytes, Base64.DEFAULT));
JSONObject head = new JSONObject();
head.put("godin_id", "0e6ad2a71e31752deb69d6e8c9eabe76");
head.put("app_type", "3");
head.put("os_type", "android");
JSONObject Request = new JSONObject();
Request.put("body", body);
Request.put("head", head);
jsonObject.put("Request", Request);
return jsonObject.toString();
}
然後在response.isSuccessful()進行判斷返回結果就可以了

由於我是直接訪問的公司上傳頭像的接口,godin_id字段是寫死的,服務端沒有注冊的記錄,所以就返回auth error的錯誤,不過我問了服務端的同事,已經收到該請求,通訊成功
我們在來看看異步上傳頭像代碼
OkHttpManger.getInstance().postAsyncJsonn("https://10.0.5.48:7771/SetVPHUserInfo", Json, new OkHttpManger.MyCallback()
public void postAsyncJsonn(String url, String json, MyCallback mCallback) throws IOException {
final RequestBody requestBody = RequestBody.create(JSON_TYPE, json);
final Request request = new Request.Builder().url(url).post(requestBody).build();
deliveryResult(mOkHttpClient.newCall(request),mCallback);
}
然後進行接口回調
private void deliveryResult(final Call call, final MyCallback mCallback) {
call.enqueue(new Callback() {
@Override
public void onFailure(final Call call, final IOException e) {
okHttpHandler.post(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
mCallback.onFailture();
}
}
});
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
final String responseStr = response.body().string();
okHttpHandler.post(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
mCallback.onSuccess(responseStr);
}
}
});
}
});
}
然後截圖是一樣的,也是可以通訊成功的。
以上就是同步、異步2種方式,上傳頭像至服務器
接下來我們看看另外一個方式,不過這個方法我沒有去實踐代碼,不過有代碼封裝,以下就是代碼
/**
* 同步基於post的文件上傳
* @param url 地址
* @param files 提交的文件數組
* @param fileKeys 提交的文件數組key
* @param params 提交的鍵值對
* @return Response
*/
public Response uploadSync(String url, File[] files, String[] fileKeys, Param[] params) throws IOException {
final RequestBody requestBody = buildMultipartFormRequestBody(files, fileKeys, params);
final Request request = new Request.Builder().url(url).post(requestBody).build();
return mOkHttpClient.newCall(request).execute();
}
/**
* 異步基於post的文件上傳,回傳上傳進度
* @param url 地址
* @param files 提交的文件數組
* @param fileKeys 提交的文件數組key
* @param params 提交的鍵值對
*/
public void uploadAsync(String url, File[] files, String[] fileKeys,
final OKHttpUICallback.ProgressCallback uploadListener, Param[] params) throws IOException {
final RequestBody requestBody = buildMultipartFormRequestBody(files, fileKeys, params);
final Request request = new Request.Builder().url(url).post(new ProgressBody.ProgressRequestBody(requestBody, uploadListener, okHttpHandler)).build();
mOkHttpClient.newCall(request).enqueue(new OKHttpThreadCallback(okHttpHandler, uploadListener, false));
}
生成post提交時的分塊request
private RequestBody buildMultipartFormRequestBody(File[] files, String[] fileKeys, Param[] params){
if(params == null){
params = new Param[0];
}
MultipartBody.Builder builder = new MultipartBody.Builder();
for(Param param:params){
builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + param.key + "\""),
RequestBody.create(null, param.value));
}
if(files == null){
files = new File[0];
}
if(fileKeys == null){
fileKeys = new String[0];
}
if(fileKeys.length != files.length){
throw new ArrayStoreException("fileKeys.length != files.length");
}
RequestBody fileBody = null;
int length = files.length;
for(int i = 0;i
我們重點來看看ProgressBody.ProgressRequestBody的代碼 Okio中有兩個關鍵的接口,Sink和Source,這兩個接口都繼承了Closeable接口;而Sink可以簡單的看做OutputStream,Source可以簡單的看做InputStream。而這兩個接口都是支持讀寫超時設置的。 它們各自有一個支持緩沖區的子類接口,BufferedSink和BufferedSource,而BufferedSink有一個實現類RealBufferedSink,BufferedSource有一個實現類RealBufferedSource
if(bufferedSink == null){
//開始包裝
bufferedSink = Okio.buffer(sink(sink));
}
//寫入
requestBody.writeTo(bufferedSink);
bufferedSink.flush();
然後在發布進度
private Sink sink(Sink sink){
return new ForwardingSink(sink) {
//當前寫入字節數
long byteWriteed = 0L;
//總得字節數
long contentBytes = 0L;
@Override
public void write(Buffer source, long byteCount) throws IOException {
super.write(source, byteCount);
if(mHandler != null && mListener != null){
if(contentBytes == 0L){
contentBytes = contentLength();
}
byteWriteed += byteCount;
mListener.onProgress(byteWriteed, contentBytes, byteWriteed == contentBytes);
}
}
};
然後在
mOkHttpClient.newCall(request).enqueue(new OKHttpThreadCallback(okHttpHandler, uploadListener, false));
在成功回調的接口中,進行如下操作
@Override
public void onResponse(Call call, Response response) throws IOException {
if(isDownload){
download(call,response);
}else{
postSuccess(call,response);
}
}
private void postSuccess(final Call call, final Response response){
if(UICallback != null && UIHandler != null){
UIHandler.post(new Runnable() {
@Override
public void run() {
UICallback.onSuccess(call, response,downFile == null?null:downFile.getAbsolutePath());
}
});
}
}
然後在主界面在進行接口回調,去實現其他一些操作
///////////////以下是代碼////////////////////以下是代碼/////////////////以下是代碼/////////////////////
MainActivity
package com.example.administrator.myapplication;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import okhttp3.Response;
public class MainActivity extends Activity implements View.OnClickListener {
Button uploadSync,uploadAsync;
private String responseStr;
private byte[] bitmap2Bytes;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
uploadSync = (Button) findViewById(R.id.uploadSync);
uploadAsync = (Button) findViewById(R.id.uploadAsync);
uploadSync.setOnClickListener(this);
uploadAsync.setOnClickListener(this);
Resources res = getResources();
Bitmap bmp = BitmapFactory.decodeResource(res, R.mipmap.ic_launcher);
bitmap2Bytes = Bitmap2Bytes(bmp);
}
public byte[] Bitmap2Bytes(Bitmap bm) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
return baos.toByteArray();
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.uploadSync:
try {
Json = createJson();
Log.i("MainActivity","postSyncByParams2 Json:"+Json);
} catch (JSONException e) {
e.printStackTrace();
}
new Thread() {
@Override
public void run() {
try {
Response response = OkHttpManger.getInstance().postSyncJson("https://10.0.5.48:7771/SetVPHUserInfo", Json);
if (response.isSuccessful()){
responseStr = response.body().string();
Log.i("MainActivity","postSyncByParams2:"+responseStr);
}else{
Log.i("MainActivity","postSyncByParams2 error");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
break;
case R.id.uploadAsync:
try {
Json = createJson();
Log.i("MainActivity","postSyncByParams2 Json:"+Json);
} catch (JSONException e) {
e.printStackTrace();
}
try {
OkHttpManger.getInstance().postAsyncJsonn("https://10.0.5.48:7771/SetVPHUserInfo", Json, new OkHttpManger.MyCallback() {
@Override
public void onSuccess(String result) {
Log.i("MainActivity","result----"+result);
}
@Override
public void onFailture() {
}
});
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
String Json = null;
private String createJson() throws JSONException {
JSONObject jsonObject = new JSONObject();
JSONObject body = new JSONObject();
body.put("photo_type", "jpeg");
body.put("nickname", "hehe");
body.put("context", Base64.encodeToString(bitmap2Bytes, Base64.DEFAULT));
JSONObject head = new JSONObject();
head.put("godin_id", "0e6ad2a71e31752deb69d6e8c9eabe76");
head.put("app_type", "3");
head.put("os_type", "android");
JSONObject Request = new JSONObject();
Request.put("body", body);
Request.put("head", head);
jsonObject.put("Request", Request);
return jsonObject.toString();
}
}
SaflyApplication
package com.example.administrator.myapplication;
import android.app.Application;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
public class SaflyApplication extends Application {
private static SaflyApplication instance;
@Override
public void onCreate() {
super.onCreate();
this.instance = this;
}
public static SaflyApplication getInstance() {
return instance;
}
public static OkHttpClient getUnsafeOkHttpClient() {
try {
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
final javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(sslSocketFactory);
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
OkHttpClient okHttpClient = builder.connectTimeout(60, TimeUnit.SECONDS).writeTimeout(60, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).build();
return okHttpClient;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
OkHttpManger
package com.example.administrator.myapplication;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.alibaba.fastjson.JSON;
import java.io.File;
import java.io.IOException;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* OkHttp 工具類,
* get的同步異步請求
* post的json字符串同步異步上傳
* post的鍵值對同步異步上傳
* post文件異步上傳,回調結果以及進度
* 異步下載文件,回調結果以及進度
*
* Created by Seeker on 2016/6/24.
*/
public final class OkHttpManger {
private static final String TAG = "OkHttpManger";
private static final MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8");
private Handler okHttpHandler;
private OkHttpClient mOkHttpClient;
private OkHttpManger(){
this.mOkHttpClient = SaflyApplication.getInstance().getUnsafeOkHttpClient();
this.okHttpHandler = new Handler(Looper.getMainLooper());
}
public static final OkHttpManger getInstance(){
return SingleFactory.manger;
}
private static final class SingleFactory{
private static final OkHttpManger manger = new OkHttpManger();
}
/////////////////////////同步異步上傳頭像//////////////////////////////
interface MyCallback{
void onSuccess(String result);
void onFailture();
}
public Response postSyncJson(String url, String json) throws IOException {
final RequestBody requestBody = RequestBody.create(JSON_TYPE, json);
final Request request = new Request.Builder().url(url).post(requestBody).build();
return mOkHttpClient.newCall(request).execute();
}
public void postAsyncJsonn(String url, String json, MyCallback mCallback) throws IOException {
final RequestBody requestBody = RequestBody.create(JSON_TYPE, json);
final Request request = new Request.Builder().url(url).post(requestBody).build();
deliveryResult(mOkHttpClient.newCall(request),mCallback);
}
private void deliveryResult(final Call call, final MyCallback mCallback) {
call.enqueue(new Callback() {
@Override
public void onFailure(final Call call, final IOException e) {
okHttpHandler.post(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
mCallback.onFailture();
}
}
});
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
final String responseStr = response.body().string();
okHttpHandler.post(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
mCallback.onSuccess(responseStr);
}
}
});
}
});
}
////////////////////////同步異步上傳頭像//////////////////////////////
/**
* 同步基於post的文件上傳
* @param url 地址
* @param file 提交的文件
* @param fileKey 提交的文件key
* @return Response
*/
public Response uploadSync(String url, File file, String fileKey) throws IOException {
return uploadSync(url, new File[]{file}, new String[]{fileKey}, new Param[0]);
}
/**
* 同步基於post的文件上傳
* @param url 地址
* @param files 提交的文件數組
* @param fileKeys 提交的文件數組key
* @param params 提交的鍵值對
* @return Response
*/
public Response uploadSync(String url, File[] files, String[] fileKeys, Param[] params) throws IOException {
final RequestBody requestBody = buildMultipartFormRequestBody(files, fileKeys, params);
final Request request = new Request.Builder().url(url).post(requestBody).build();
return mOkHttpClient.newCall(request).execute();
}
/**
* 異步基於post的文件上傳,回傳上傳進度
* @param url 地址
* @param file 提交的文件
* @param fileKey 提交的文件key
*/
public void uploadAsync(String url, File file, String fileKey, OKHttpUICallback.ProgressCallback listener)
throws IOException {
uploadAsync(url, new File[]{file}, new String[]{fileKey}, listener, new Param[0]);
}
/**
* 異步基於post的文件上傳,回傳上傳進度
* @param url 地址
* @param files 提交的文件數組
* @param fileKeys 提交的文件數組key
* @param params 提交的鍵值對
*/
public void uploadAsync(String url, File[] files, String[] fileKeys,
final OKHttpUICallback.ProgressCallback uploadListener, Param[] params) throws IOException {
final RequestBody requestBody = buildMultipartFormRequestBody(files, fileKeys, params);
final Request request = new Request.Builder().url(url).post(new ProgressBody.ProgressRequestBody(requestBody, uploadListener, okHttpHandler)).build();
mOkHttpClient.newCall(request).enqueue(new OKHttpThreadCallback(okHttpHandler, uploadListener, false));
}
/**
* 生成post提交時的分塊request
* @param files
* @param fileKeys
* @param params
* @return
*/
private RequestBody buildMultipartFormRequestBody(File[] files, String[] fileKeys, Param[] params){
if(params == null){
params = new Param[0];
}
MultipartBody.Builder builder = new MultipartBody.Builder();
for(Param param:params){
builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + param.key + "\""),
RequestBody.create(null, param.value));
}
if(files == null){
files = new File[0];
}
if(fileKeys == null){
fileKeys = new String[0];
}
if(fileKeys.length != files.length){
throw new ArrayStoreException("fileKeys.length != files.length");
}
RequestBody fileBody = null;
int length = files.length;
for(int i = 0;i<length;i++){ contenttype="" file="" filebody="RequestBody.create(MediaType.parse(guessMimeType(fileName)),file);" filename="file.getName();" filenamemap="" final="" name="\" pre="" private="" public="" return="" static="" string="" this.key="key;" this.value="value;" todo="" type="=">
ProgressBody 上傳的進度接口
package com.example.administrator.myapplication;
import android.os.Handler;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.ForwardingSink;
import okio.ForwardingSource;
import okio.Okio;
import okio.Sink;
import okio.Source;
/**
* Created by Seeker on 2016/7/27.
*/
public final class ProgressBody {
/**
* 包裝響應體,用於處理提示上傳進度
*
* Created by Seeker on 2016/6/29.
*/
public static final class ProgressRequestBody extends RequestBody {
//實際待包裝的請求體
private final RequestBody requestBody;
//上傳進度回調接口
private OKHttpUICallback.ProgressCallback mListener;
//包裝完成的BufferedSink
private BufferedSink bufferedSink;
//傳遞下載進度到主線程
private Handler mHandler;
public ProgressRequestBody(RequestBody requestBody, OKHttpUICallback.ProgressCallback listener, Handler handler){
this.requestBody = requestBody;
this.mListener = listener;
this.mHandler = handler;
}
@Override
public long contentLength() throws IOException {
return requestBody.contentLength();
}
@Override
public MediaType contentType() {
return requestBody.contentType();
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
if(bufferedSink == null){
//開始包裝
bufferedSink = Okio.buffer(sink(sink));
}
//寫入
requestBody.writeTo(bufferedSink);
bufferedSink.flush();
}
/**
* 寫入,回調進度接口
*/
private Sink sink(Sink sink){
return new ForwardingSink(sink) {
//當前寫入字節數
long byteWriteed = 0L;
//總得字節數
long contentBytes = 0L;
@Override
public void write(Buffer source, long byteCount) throws IOException {
super.write(source, byteCount);
if(mHandler != null && mListener != null){
if(contentBytes == 0L){
contentBytes = contentLength();
}
byteWriteed += byteCount;
mListener.onProgress(byteWriteed, contentBytes, byteWriteed == contentBytes);
}
}
};
}
}
}
OKHttpThreadCallback上傳完畢後的接口方法
package com.example.administrator.myapplication;
import android.os.Handler;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
public final class OKHttpThreadCallback implements Callback {
private Handler UIHandler;
private OKHttpUICallback.ProgressCallback UICallback;
private boolean isDownload;
private File downFile;
public OKHttpThreadCallback(Handler handler, OKHttpUICallback.ProgressCallback callback, boolean isDownload){
this.UIHandler = handler;
this.UICallback = callback;
this.isDownload = isDownload;
}
@Override
public void onFailure(final Call call, final IOException e) {
if(UICallback != null && UIHandler != null){
UIHandler.post(new Runnable() {
@Override
public void run() {
UICallback.onError(call,e);
}
});
}
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if(isDownload){
download(call,response);
}else{
postSuccess(call,response);
}
}
/**
* 設置保存file
* @param file
*/
public OKHttpThreadCallback setFile(File file){
this.downFile = file;
return this;
}
/**
* 獲取下載數據並寫入文件
* @param response
*/
private void download(Call call, Response response) throws IOException {
if(downFile == null){
throw new NullPointerException("downFile == null");
}
byte[] buffer = new byte[2048];
InputStream is = response.body().byteStream();
int len;
FileOutputStream fos = new FileOutputStream(downFile);
while ((len = is.read(buffer)) != -1){
fos.write(buffer,0,len);
}
fos.flush();
if(is != null){
is.close();
}
if (fos != null){
fos.close();
}
postSuccess(call,null);
}
/**
* 回調成功信息
* @param call
* @param response
*/
private void postSuccess(final Call call, final Response response){
if(UICallback != null && UIHandler != null){
UIHandler.post(new Runnable() {
@Override
public void run() {
UICallback.onSuccess(call, response,downFile == null?null:downFile.getAbsolutePath());
}
});
}
}
}
OKHttpUICallback成功後需要實現的接口定義類
package com.example.administrator.myapplication;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import okhttp3.Call;
import okhttp3.Response;
/**
* Created by safly on 2016/9/1.
*
* 回調主線程的接口
*/
public class OKHttpUICallback {
/**
* 異步回調接口
*/
/**
* 帶有進度的上傳、下載回調接口
*/
public interface ProgressCallback{
void onSuccess(Call call, Response response, String path);
void onProgress(long byteReadOrWrite, long contentLength, boolean done);
void onError(Call call, IOException e);
}
}
Android拼圖游戲的設計邏輯,實例提高!
群英傳的最後一章,我大致的看了一下這個例子,發現鴻洋大神也做過,就參考兩個人的設計邏輯,感覺都差不多,就這樣實現起來了一.切圖工具類 我們九宮格嘛,肯定要一
安卓盒子launcher界面開發之添加自動定位,獲取當地天氣
最近老板要求在launcher界面做個自動定位,並獲取當地天氣的功能,中間走了不少彎路,我在這裡都寫下來,希望看到這篇文章的人,能少走點彎路。1、接到任務後,我首先想的是
Android 中自定義View的初步總結
概述在開發過程中,經常會遇到系統中提供的控件無法滿足產品的設計需求,這時可能就需要考慮使用自定義的View來實現產品的設計細節了。對於自定義View,可以分為兩種,一種是
分析Dalvik字節碼進行減包優化
Android結合版最近幾個版本在包大小配額上超標了,先後采用了包括圖片壓縮,功能H5,無用代碼移除等手段減包,還是有著很大的減包壓力。組內希望我能從代碼的角度減少一些包