Today I'm trying to upload and image to a server. I found that a lot of developers recommend the use of HttpURLConnection. The performance is very important for me, so I tried to optimize the code the most I know how to do it. The problem I faced is that the uploaded images are considerably larger than the original ones.
If anyone sees something that can be done better, it would be of great help
This is my class to upload a bitmap:
private class SubirImagen extends AsyncTask<Bitmap, Integer, APIResponse<String>> {
String token;
String boundary = "***" + System.currentTimeMillis() + "***";
String crlf = "\r\n";
String twoHyphens = "--";
public SubirImagen(String token) {
this.token = token;
}
@Override
protected void onPostExecute(APIResponse<String> stringAPIResponse) {
progressBar.setVisibility(View.INVISIBLE);
if (stringAPIResponse.getErrors().isEmpty()) {
new File(pathToFile.getPath()).delete();
imagenCambiada = false;
pathToFile = null;
controler.showToast(getContext(), stringAPIResponse.getData());
} else {
controler.showToast(getContext(), stringAPIResponse.getErrors().get(0).getErrorMsg());
}
super.onPostExecute(stringAPIResponse);
}
@Override
protected void onPreExecute() {
progressBar.setVisibility(View.VISIBLE);
progressBar.setProgress(0);
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Integer... values) {
progressBar.setProgress(values[0]);
}
@Override
protected APIResponse<String> doInBackground(Bitmap... bitmaps) {
ByteArrayOutputStream bao1 = new ByteArrayOutputStream();
bitmaps[0].compress(Bitmap.CompressFormat.JPEG, 100, bao1);
byte[] ba1 = bao1.toByteArray();
int size = (twoHyphens.length() * 3) + (boundary.length() * 2) + (crlf.length() * 5) +
("Content-Disposition: form-data; name=\"imagen\";filename=\"imagen\"".length()) +
ba1.length;
HttpURLConnection urlConnection = null;
try {
URL url = new URL("http://192.168.137.1:8080/BochoGameAPI/usuario/uploadFotoPerfil");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestProperty("Authorization", token);
urlConnection.setUseCaches(false);
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Connection", "Keep-Alive");
urlConnection.setRequestProperty("Cache-Control", "no-cache");
urlConnection.setRequestProperty("ENCTYPE", "multipart/form-data");
urlConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
urlConnection.setFixedLengthStreamingMode(size);
DataOutputStream request = new DataOutputStream(urlConnection.getOutputStream());
request.writeBytes(twoHyphens + boundary + crlf);
request.writeBytes("Content-Disposition: form-data; name=\"imagen\";filename=\"imagen\"" + crlf);
request.writeBytes(crlf);
request.flush();
int progress = 0;
int bytesRead;
byte buf[] = new byte[1024];
BufferedInputStream bufInput = new BufferedInputStream(new ByteArrayInputStream(ba1));
while ((bytesRead = bufInput.read(buf)) != -1) {
// write output
request.write(buf, 0, bytesRead);
request.flush();
progress += bytesRead;
// update progress bar
publishProgress((progress * 100) / size);
}
request.write(ba1);
request.writeBytes(crlf);
request.writeBytes(twoHyphens + boundary + twoHyphens + crlf);
request.flush();
request.close();
int code = urlConnection.getResponseCode();
if (code != 200) {
throw new IOException("Invalid response from server: " + code);
}
BufferedReader rd = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream()));
String line;
Gson gson = new Gson();
Type typeToken = new TypeToken<APIResponse<String>>() {
}.getType();
APIResponse<String> apiResponse = null;
while ((line = rd.readLine()) != null) {
apiResponse = gson.fromJson(line, typeToken);
}
rd.close();
return apiResponse;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return null;
}
}
Original image, 1.57 mb:
Uploaded image, 4.19 mb: