aim using HttpURLConnection inside AsyncTask when i cancel AsyncTask and request abort or cancel the connection the AsyncTask stoped ok but HttpURLConnection still sending request and return with the values from the server
how i can make HttpURLConnection full stop cancel all requests or abort the request ?
this is the code i use
public static String post_string(String url, String urlParameters) throws IOException
{
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) new URL(url).openConnection();
} catch (MalformedURLException e) {
Log.e(Logger, "MalformedURLException While Creating URL Connection - " + e.getMessage());
throw e;
} catch (IOException e) {
Log.e(Logger, "IOException While Creating URL Connection - " + e.getMessage());
throw e;
}
conn.setDoOutput(true);
conn.addRequestProperty("User-Agent", "Mozilla/5.0");
conn.setRequestProperty("Accept-Charset", "UTF-8");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
//if has Post inputs
conn.setRequestProperty("Content-Length", Integer.toString(urlParameters.length()));
OutputStream os = null;
System.setProperty("http.keepAlive", "false");
try {
os = conn.getOutputStream();
} catch (IOException e) {
Log.e(Logger, "IOException While Creating URL OutputStream - " + e.getMessage());
throw e;
}
try {
os.write(urlParameters.toString().getBytes());
} catch (IOException e) {
Log.e(Logger, "IOException While writting URL OutputStream - " + e.getMessage());
throw e;
}
InputStream in = null;
try {
in = conn.getInputStream();
} catch (IOException e) {
Log.e(Logger, "IOException While Creating URL InputStream - " + e.getMessage());
throw e;
}
String output = null;
try {
output = slurp(in);
} catch (IOException e) {
Log.e(Logger, "IOException While Reading URL OutputStream - " + e.getMessage());
throw e;
} finally {
try {
os.close();
in.close();
} catch (IOException e) {
Log.e(Logger, "IOException While Closing URL Output and Input Stream - " + e.getMessage());
}
}
conn.disconnect();
Log.i("Server output " , output);
return output;
}
private static String slurp(InputStream in) throws IOException
{
StringBuffer out = new StringBuffer();
byte[] b = new byte[4096];
for (int n; (n = in.read(b)) != -1;) {
out.append(new String(b, 0, n));
}
return out.toString();
}
and this is what i use to abort connection
conn.disconnect();
any advice how to abort ?
When you stop your AsyncTask like mTask.cancel(true); just call conn.disconnect();
Related
I'm using HttpURLConnection to retrieve some configuration from a server. It works fine but for some reason I'm getting the following warning in the logcat:
OkHttpClient: A connection to ... was leaked. Did you forget to close a response body?
As pointed out in this question, Android is using OkHttp internally in HttpUrlConnection. What am I doing to cause this warning?
Here is the code I'm using:
HttpURLConnection connection = null;
OutputStream outputStream = null;
String result;
try {
URL url = new URL(CONFIG_URL);
connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout(READ_TIMEOUT_MILLI);
connection.setConnectTimeout(CONNECT_TIMEOUT_MILLI);
connection.setRequestMethod(REQUEST_METHOD);
connection.setDoInput(true);
connection.addRequestProperty("Content-Type", "application/json");
connection.addRequestProperty("Accept", "application/json");
outputStream = connection.getOutputStream();
try (DataOutputStream wr = new DataOutputStream(outputStream)) {
wr.write(data.toString().getBytes(STRING_ENCODING));
wr.flush();
wr.close();
int responseCode = connection.getResponseCode();
if (responseCode != HttpsURLConnection.HTTP_OK) {
Log.e(TAG, "HTTP error code: " + responseCode);
return;
}
try (InputStream stream = connection.getInputStream()) {
if (stream != null) {
result = readStream(stream, READ_STREAM_MAX_LENGTH_CHARS);
//...
connection.disconnect();
}
} catch (Throwable e) {
Log.e(TAG, "run: failed to parse server response: " +e.getMessage());
}
}
} catch (Exception e) {
Log.e(TAG, "HttpSendTask: failed to send configuration request " + data +": " +e.getMessage());
} finally {
if (outputStream != null) {
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection != null) {
connection.disconnect();
}
}
Closing the inputstream of the connection solved my problem.
Try to close it in the finally block :
connection.getInputStream().close()
I have a HTTP handler class that will handle the calls to a ASYNC method. Everything works fine, I am able to gather information from the json and display it inside of the application, however, I have noticed that I sometimes get the following in my log.
A connection to http://www.abc123.com/ was leaked. Did you forget to close a response body?
Is there any specific reason why I would be getting this. I am closing in within the try method in convertStreamToString.
public class HttpHandler {
private static final String TAG = HttpHandler.class.getSimpleName();
public HttpHandler() {
}
public String makeServiceCall(String reqUrl) {
String response = null;
try {
URL url = new URL(reqUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
// read the response
InputStream in = new BufferedInputStream(conn.getInputStream());
response = convertStreamToString(in);
} catch (MalformedURLException e) {
Log.e(TAG, "MalformedURLException: " + e.getMessage());
} catch (ProtocolException e) {
Log.e(TAG, "ProtocolException: " + e.getMessage());
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.getMessage());
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
return response;
}
private String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line).append('\n');
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
I'm having trouble catching a response to a POST request to server, when the server takes a bit longer to respond (when it is passed a bigger JSONObject).
When we call a GET method with a longer response time, there is no problem. When we call a POST and pass a relatively small JSONObject, the method registers a response.
The method is being called from an AsyncTask via new Task().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR).
When triggered from Postman, the response returns after 155 seconds, but it arrives. On the other hand, when triggered from the app, the code does nothing and ultimately tiggers a SocketTimeoutException.(For whatever reason, we have a timeout(connection and read timeout) set to 10 minutes) The code snippet for the service method is below. I'd appreciate any hints.
public static JSONObject requestWebService(String serviceUrl, JSONObject jsonObject) throws Exception {
private static final int CONNECTION_TIMEOUT = 1000 * 600;
private static final int DATARETREIVAL_TIMEOUT = 1000 * 600
HttpURLConnection urlConnection = null;
try {
URL urlToRequest;
String message;
urlToRequest = new URL(serviceUrl);
urlConnection = (HttpURLConnection) urlToRequest.openConnection();
urlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
urlConnection.setReadTimeout(DATARETREIVAL_TIMEOUT);
if (jsonObject != null) {
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json");
message = jsonObject.toString();
OutputStream os = new BufferedOutputStream(urlConnection.getOutputStream());
os.write(message.getBytes());
os.flush();
os.close();
} else {
urlConnection.setRequestMethod("GET");
}
int statusCode = urlConnection.getResponseCode();
if (statusCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
throw new Exception("Acces unauthorized " + statusCode + ".");
} else if (statusCode != HttpURLConnection.HTTP_OK) {
throw new Exception("Server unavailable " + statusCode + ".");
}
return new JSONObject(ReplicationClient.convertInputStreamToString(urlConnection.getInputStream()));
} catch (MalformedURLException e) {
fileLogger.error(logHeader + e.getMessage(), e);
throw new Exception("Error " + e.getMessage(), e);
} catch (SocketTimeoutException e) {
fileLogger.error(logHeader + e.getMessage(), e);
throw new Exception("Error " + e.getMessage(), e);
} catch (IOException e) {
fileLogger.error(logHeader + e.getMessage(), e);
throw new Exception("Error " + e.getMessage(), e);
} catch (JSONException e) {
fileLogger.error(logHeader + e.getMessage(), e);
throw new Exception("Error " + e.getMessage(), e);
} catch (Exception e) {
fileLogger.error(logHeader + e.getMessage(), e);
throw new Exception("Error " + e.getMessage(), e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
}
after a second thought i have a theory
i will explain in details
but first try this code for writing data:
remove this from your code:
OutputStream os = new BufferedOutputStream(urlConnection.getOutputStream());
os.write(message.getBytes());
os.flush();
os.close();
use this:
OutputStream os = urlConnection.getOutputStream();
os.write( message.getBytes());
os.close();
if this works, then i will edit this answer and explain more.
This answer did not help as per the OP comment.
I am keeping this in case i found something else, otherwise, i will delete it later.
I am trying to connect to web services running on my machine(localhost). I have tested from restClient and its working fine. But, I am unable to test them from android application(which I am working on). There seems to be a connection problem.
This is the calling code:
#Override
protected Void doInBackground(String... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String mobileNo = params[0];
String format = "json";
try {
// Construct the URL for Login
JSONObject requestObject = new JSONObject();
requestObject.put(MOBILE_NO, mobileNo);
final String LOGIN_BASE_URL =
"http://192.168.42.251:8080/SpringSample/login";
Uri builtUri = Uri.parse(LOGIN_BASE_URL).buildUpon()
.build();
URL url = new URL(builtUri.toString());
// Create the request to OpenWeatherMap, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.connect();
// Request Body
OutputStream outStream = urlConnection.getOutputStream();
if (outStream == null) {
throw new ConnectException();
}
outStream.write(requestObject.toString().getBytes());
int responseCode = urlConnection.getResponseCode();
if (responseCode == 409) {
} else if (responseCode == 201) {
} else {
throw new ConnectException();
}
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
} catch (JSONException e) {
Log.e(LOG_TAG, "Error ", e);
} catch (ConnectException e) {
Log.e(LOG_TAG, "Error ", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, "Error closing stream", e);
}
}
}
return null;
}
Exception is :
Caused by: android.system.ErrnoException: connect failed: ETIMEDOUT (Connection timed out)
I've some problems with InputStream after download an image. downloadImages method return an InputStream that i write in a file. But there is an exception in inputStreamToFile method: java.io.IOException: BufferedInputStream is closed. Here the codes:
Download
public static InputStream downloadImages(String imageUrl) {
HttpURLConnection httpConn = null;
String urlBase = imageUrl;
if(D) Log.d(TAG, "downloadImages(): url request: " + urlBase);
try {
URL url = new URL(urlBase);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setConnectTimeout(SystemConstants.TIMEOUT_CONNECTION);
httpConn.setReadTimeout(SystemConstants.SOCKET_CONNECTION);
if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream inputStream = httpConn.getInputStream();
return inputStream;
}
} catch (IOException e) {
Log.w(TAG, "downloadImages(): exception: " + e);
e.printStackTrace();
return null;
} catch (Exception e) {
e.printStackTrace();
} finally {
if(httpConn != null) httpConn.disconnect();
}
return null;
}
From IS to file
public static void inputStreamToFile(InputStream is) {
if(D) Log.d(TAG, "inputStreamToFile() called");
OutputStream outputStream = null;
try {
// Check if media is mounted or storage is built-in, if so, try and use external cache dir
// otherwise use internal cache dir
final String cachePath =
Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ||
!Utils.isExternalStorageRemovable() ?
Utils.getExternalCacheDir(App.getContext()).getPath() :
App.getContext().getCacheDir().getPath();
// write the inputStream to a FileOutputStream
outputStream = new FileOutputStream(new File(cachePath + File.separator + "vr"));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = is.read(bytes)) != -1) {
if(D) Log.d(TAG, "read called");
outputStream.write(bytes, 0, read);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
if(D) Log.d(TAG, "inputStreamToFile(): outputStream is not null");
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Put your logcat.Then only we can identify the errors,bugs,etc