I'm using HttpUrlConnection in my android app. I'm trying to send a post request to a particular url every 2 seconds. Below is the code for the same.
The issue I have is, I get 200 OK response for the first approx 200-250 calls, and after that every call starts failing with 400 Bad requestYour browser sent an invalid request.
I force stop my app, and then as mentioned above the first 200-250 hits to my url comes with 200 OK and then starts failing with 400. I was able to reproduce this consistently every time. I tried almost like 10 times and the same thing happens.
When I tried AndroidHttpClient I was able to make close to like 15000 hits to the same url without a single failure, so definitely not a server issue.
I'm trying to understand what is the issue with httpUrlConnection, as I would like to stick with httpUrlConnection as it is recommended by Google. As far as I see I have done all error handling fine.
I even tried to set http.keepAlive System property to false at the start of my appln/ included connection "Close" header before making the connection but nothing helped.
Could someone help me understand what am I doing wrong here?
HttpURLConnection con = null;
final BufferedReader rd = null;
final BufferedOutputStream wr = null;
final InputStreamReader isr = null;
ServerConnectionData serverConnectionData = null;
try {
serverConnectionData = (ServerConnectionData) connectionData;
final String urlPath = serverConnectionData.getUrlPath();
final URL url = new URL(urlPath);
trust();
HttpsURLConnection.setDefaultHostnameVerifier(new NullHostNameVerifier());
final URLConnection urlConnection = url.openConnection();
con = (HttpURLConnection) urlConnection;
con.setRequestMethod("POST");
// con.addRequestProperty("Connection", "Keep-Alive");
// con.addRequestProperty("Connection", "Close");
if (serverConnectionData.getJsonData() != null) {
con.addRequestProperty(
"Content-Length",
Integer.toString(serverConnectionData.getJsonData().getBytes(
Charset.forName("UTF8")).length));
}
if (serverConnectionData.getAdditionalHeaders() != null) {
final Map<String, String> additionalHeaders =
serverConnectionData.getAdditionalHeaders();
final Set<String> keySet = additionalHeaders.keySet();
for (final Object key : keySet) {
con.addRequestProperty((String) key, additionalHeaders.get(key));
}
}
final String authToken = "Bearer " + "my outh token";
con.addRequestProperty("Authorization", authToken);
con.addRequestProperty("Content-Type", "application/json; charset=UTF-8");
con.setUseCaches(false);
con.setConnectTimeout(60000);
con.setDoInput(true);
con.setDoOutput(true);
con.connect();
sendData(con, serverConnectionData);
responseCode = con.getResponseCode();
responseText = getResponseText(con);
if (responseCode == 200) {
// success
} else {
// failure }
}
} catch (final MalformedURLException e) {
throw new ConnectionException(ErrorCodes.SERVER_CONNECTION_ERROR, e.getStackTrace());
} catch (final IOException e) {
Log.e(e.toString());
try {
if (null != con) {
responseCode = con.getResponseCode();
responseText = getResponseText(con);
}
if (responseCode == 401) {
// handle 401 response
} else {
final ConnectionException ce =
new ConnectionException(ErrorCodes.SERVER_CONNECTION_ERROR,
e.getStackTrace());
ce.setResponseCode(responseCode);
throw ce;
}
} catch (final UnsupportedEncodingException uee) {
throw new ConnectionException(ErrorCodes.SERVER_CONNECTION_ERROR,
uee.getStackTrace());
} catch (final IOException ioe) {
throw new ConnectionException(ErrorCodes.SERVER_CONNECTION_ERROR,
ioe.getStackTrace());
}
} catch (final KeyManagementException e) {
throw new ConnectionException(ErrorCodes.SERVER_CONNECTION_ERROR, e.getStackTrace());
} catch (final NoSuchAlgorithmException e) {
throw new ConnectionException(ErrorCodes.SERVER_CONNECTION_ERROR, e.getStackTrace());
} catch (final Exception e) {
throw new ConnectionException(ErrorCodes.SERVER_CONNECTION_ERROR, e.getStackTrace());
} finally {
if (wr != null) {
try {
wr.flush();
wr.close();
} catch (final IOException e) {
throw new ConnectionException(ErrorCodes.SERVER_CONNECTION_ERROR,
e.getStackTrace());
}
}
if (isr != null) {
try {
isr.close();
} catch (final IOException e) {
throw new ConnectionException(ErrorCodes.SERVER_CONNECTION_ERROR,
e.getStackTrace());
}
}
if (rd != null) {
try {
rd.close();
} catch (final IOException e) {
throw new ConnectionException(ErrorCodes.SERVER_CONNECTION_ERROR,
e.getStackTrace());
}
}
if (con != null) {
con.disconnect();
}
}
private void trust() throws NoSuchAlgorithmException, KeyManagementException {
final TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
#Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
#Override
public void checkClientTrusted(final java.security.cert.X509Certificate[] certs,
final String authType) {
}
#Override
public void checkServerTrusted(final java.security.cert.X509Certificate[] certs,
final String authType) {
}
}
};
final SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
public void sendData(final HttpURLConnection con, final ServerConnectionData serverConnectionData)
throws IOException, ConnectionException {
final String requestJSON = serverConnectionData.getJsonData();
if (requestJSON != null) {
BufferedOutputStream bufferedOutputStream = null;
try {
bufferedOutputStream = new BufferedOutputStream(con.getOutputStream());
bufferedOutputStream.write(requestJSON.getBytes());
bufferedOutputStream.flush();
} finally {
if (bufferedOutputStream != null) {
try {
bufferedOutputStream.flush();
bufferedOutputStream.close();
} catch (final IOException e) {
setOnlineStatus(ONLINE_STATUS_BAD);
throw new ConnectionException(ErrorCodes.SERVER_CONNECTION_ERROR,
e.getStackTrace());
}
}
}
}
}
public String getResponseText(final HttpURLConnection con) throws IOException {
InputStream stream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
String responseText = null;
try {
final int responseCode = con.getResponseCode();
if (200 == responseCode) {
stream = con.getInputStream();
}
if (null == stream) {
stream = con.getErrorStream();
}
if (null == stream) {
return "";
}
inputStreamReader = new InputStreamReader(stream, "UTF8");
bufferedReader = new BufferedReader(inputStreamReader);
final StringBuilder sb = new StringBuilder("");
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
responseText = sb.toString();
} finally {
if (bufferedReader != null) {
bufferedReader.close();
}
if (inputStreamReader != null) {
inputStreamReader.close();
}
if (stream != null) {
stream.close();
}
}
return responseText;
}
Related
I have implemented AsyncTask in Activity properly (based on many sources).
Also I have investigated SocketTimeoutException and catche exception as you can see in the code below.
Anyway when I stop webapi and simulate SocketTimeoutException the app crashes immediately. (Please, check the error's message.)
Debuging code goes to IOException and then I see the error's message and app restarts.
Code
private class FetchHauls extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
try {
AppSettings.ComplexPreferences complexPreferences = AppSettings.ComplexPreferences.getComplexPreferences(context, "App_Settings", 0);
AppSettings appSettings = complexPreferences.getObject("App_Settings", AppSettings.class);
if (appSettings != null) {
String uri = appSettings.getIpAddress() + "/api/Version1/GetGrandTotalStats";
GrandTotalStatsRequest grandTotalStatsRequest = new GrandTotalStatsRequest();
Date d = new Date();
CharSequence timeOfRequest = DateFormat.format("yyyy-MM-dd HH:mm:ss", d.getTime());
grandTotalStatsRequest.AtTime = timeOfRequest.toString();
grandTotalStatsRequest.DeviceID = appSettings.getDeviceID();
grandTotalStatsRequest.DeviceSerialNumber = appSettings.getSerialNumber();
Gson gson = new Gson();
String json = gson.toJson(grandTotalStatsRequest);
//Connect
urlConnection = (HttpURLConnection) ((new URL(uri).openConnection()));
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setRequestMethod("POST");
urlConnection.setConnectTimeout(60000);
urlConnection.setReadTimeout(55000);
urlConnection.connect();
//Write
OutputStream outputStream = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
writer.write(json);
writer.close();
outputStream.close();
String result = null;
//Read
InputStream inputStream = urlConnection.getInputStream();
if (inputStream != null) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String l = null;
StringBuilder sb = new StringBuilder();
while ((l = bufferedReader.readLine()) != null) {
sb.append(l);
}
bufferedReader.close();
result = sb.toString();
}
return result;
}
} catch (IOException e) {
} catch (Exception e) {
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException ex) {
}
}
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (isCancelled()) {
return;
}
swiperefresh.setRefreshing(false);
taskFetchHauls = null;
if (TextUtils.isEmpty(s)) return;
try {
// Some code...
} catch (Exception ex) {
Log.e(PAGE_TITLE, ex.getMessage());
}
}
}
}
Error
java.net.SocketTimeoutException: failed to connect to /172.15.15.2 (port 1067) after 60000ms
at libcore.io.IoBridge.connectErrno(IoBridge.java:169)
at libcore.io.IoBridge.connect(IoBridge.java:122)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:452)
at java.net.Socket.connect(Socket.java:884)
at com.android.okhttp.internal.Platform.connectSocket(Platform.java:117)
at com.android.okhttp.internal.http.SocketConnector.connectRawSocket(SocketConnector.java:160)
at com.android.okhttp.internal.http.SocketConnector.connectCleartext(SocketConnector.java:67)
at com.android.okhttp.Connection.connect(Connection.java:152)
at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185)
at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:433)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:114)
at android.apps.ktk.company.gpsmegatracker.Activities.GrandStatActivity$FetchHauls.doInBackground(GrandStatActivity.java:291)
at android.apps.ktk.company.gpsmegatracker.Activities.GrandStatActivity$FetchHauls.doInBackground(GrandStatActivity.java:259)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Disconnected from the target VM, address: 'localhost:8617', transport: 'socket'
If you want to catch a SocketTimeoutException, then you should use the following pattern. Note carefully that we catch exceptions from most specific to most general. Because SocketTimeoutException is a child of IOException, we catch the former first. Using the reverse order will result in the error you were seeing. Finally, we catch general Exception last.
#Override
protected String doInBackground(String... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
try {
// make the async call
}
catch (SocketTimeoutException se) {
// display timeout alert to user
}
catch (IOException e) {
// handle general IO error
}
catch (Exception e) {
// just in case you missed anything else
}
finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException ex) {
}
}
}
}
I try to execute an AsyncTask like this
private static final String REQUESTED_URL = "//my url";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.earthquake_activity);
EarthQuakeAsyncTask task = new EarthQuakeAsyncTask();
task.execute(REQUESTED_URL); //this is where the error is
}
but Android Studio said that it cannot resolve method execute(String). I'm having a tutorial from Udacity, their sample is pretty much similar
/** URL for earthquake data from the USGS dataset */
private static final String USGS_REQUEST_URL =
"//url";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EarthquakeAsyncTask task = new EarthquakeAsyncTask();
task.execute(USGS_REQUEST_URL); //it works
}
Can someone tell me why this possibly occurs?
Edit: this is my EarthQuakeAsyncTask class:
private class EarthQuakeAsyncTask extends AsyncTask<URL,Void,ArrayList<EarthQuake>> {
#Override
protected ArrayList<EarthQuake> doInBackground(URL... urls) {
if(urls.length==0||urls[0]== null){
return null;
}
// Create URL object
URL url = createUrl(REQUESTED_URL);
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
// TODO Handle the IOException
}
ArrayList<EarthQuake> earthquake = QueryUtils.extractEarthquakes(jsonResponse);
return earthquake;
}
#Override
protected void onPostExecute(ArrayList<EarthQuake> earthquake) {
if (earthquake == null) {
return;
}
updateUi();
}
private URL createUrl(String stringUrl) {
URL url;
try {
url = new URL(stringUrl);
} catch (MalformedURLException exception) {
Log.e(LOG_TAG, "Error with creating URL", exception);
return null;
}
return url;
}
private String makeHttpRequest(URL url) throws IOException {
// If the URL is null, then return early.
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return jsonResponse;
}
private String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
}
}
Your class signature suggests that you are expecting a URL type as parameter, but you are passing a String type in the execute() method. All you need to do is to change your class signature to expect a String as in the one in this code.
private class EarthQuakeAsyncTask extends AsyncTask<String,Void,ArrayList<EarthQuake>> {
#Override
protected ArrayList<EarthQuake> doInBackground(String... urls) {
if(urls.length==0||urls[0]== null){
return null;
}
// Create a URL object from the String passed to the execute method
URL url = createUrl(urls[0]);
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
// TODO Handle the IOException
}
ArrayList<EarthQuake> earthquake = QueryUtils.extractEarthquakes(jsonResponse);
return earthquake;
}
#Override
protected void onPostExecute(ArrayList<EarthQuake> earthquake) {
if (earthquake == null) {
return;
}
updateUi();
}
private URL createUrl(String stringUrl) {
URL url;
try {
url = new URL(stringUrl);
} catch (MalformedURLException exception) {
Log.e(LOG_TAG, "Error with creating URL", exception);
return null;
}
return url;
}
private String makeHttpRequest(URL url) throws IOException {
// If the URL is null, then return early.
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return jsonResponse;
}
private String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
}
}
That is because your AsyncTask class isn't defined in a manner to handle the execute method with a String parameter. Let me explain myself.
The AsyncTask class you develop will look like this:
private class MyAsyncTask extends AsyncTask<TYPE1, TYPE2, TYPE3> {
protected TYPE3 doInBackground(TYPE1... type1_variables) {
// Do some long process here..
return variable_of_type_TYPE3;
}
protected void onPostExecute(TYPE3 result) {
// Do something here
}
}
So for you to call task.execute(REQUESTED_URL); you'd need to implement your AsyncTask class correctly.
For example it might look like this:
private class EarthQuakeAsyncTask extends AsyncTask<String, Void, Void> {
...
}
Here is my code:
public class HttpClient {
public String AddressBase = "";
String _AccessToken = "";
String _AccessToken = "";
public HttpClient() {
}
public HttpClient(String accessToken) {
_AccessToken = accessToken;
}
private HttpURLConnection _CreateConnection(String url, final ArrayList<Pair<String, String>> params) throws IOException {
Uri.Builder uriB1 = Uri.parse(AddressBase).buildUpon()
.appendEncodedPath(url);
if (params != null)
for (Pair<String, String> p :
params) {
uriB1 = uriB1.appendQueryParameter(p.first, p.second);
}
URL callUrl = new URL(uriB1.build().toString());
HttpURLConnection connection = (HttpURLConnection) callUrl.openConnection();
if (!_AccessToken.isEmpty())
connection.setRequestProperty("Authorization", "Bearer " + _AccessToken);
return connection;
}
private <T, Y> Y _Post(final String url, final ArrayList<Pair<String, String>> params, final T object, final Class<Y> objectClass) {
Log.e("check net", "_post");
return _Post(url, params, AppConstants.Gson_Get().toJson(object), "application/json", objectClass);
}
private <Y> Y _Post(final String url, final ArrayList<Pair<String, String>> params, final String postBodyContent, String postBodyContentType, final Class<Y> objectClass) {
Y r = null;
HttpURLConnection connection = null;
try {
Log.e("tag", " try create connection");
connection = _CreateConnection(url, params);
connection.setRequestMethod("POST");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Content-type", postBodyContentType);
connection.setRequestProperty("Accept-Encoding", "gzip");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
if (postBodyContent != null && !postBodyContent.isEmpty()) {
OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
wr.write(postBodyContent);
wr.flush();
}
connection.connect();
Log.e("tag", " connection connected");
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
String h1 = connection.getHeaderField("Content-Encoding");
if (h1 != null && h1.equalsIgnoreCase("gzip")) {
inputStream = new GZIPInputStream(inputStream);
}
String resultString = _ConvertStreamToString(inputStream);
inputStream.close();
r = AppConstants.Gson_Get().fromJson(resultString, objectClass);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (Exception e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
if (connection != null)
connection.disconnect();
return r;
}
private String _ConvertStreamToString(InputStream inputStream) {
Log.e("checknet", "cnovert stram to string");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder = new StringBuilder();
String line = null;
try {
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
return stringBuilder.toString();
}
public <T, Y> Y Post(final String url, final T object, final Class<Y> objectClass) {
return _Post(url, null, object, objectClass);
}
public <T> T PostParamsInQuery(String url, final ArrayList<Pair<String, String>> params, final Class<T> objectClass) {
return _Post(url, params, null, "application/json", objectClass);
}
public <T> T PostParamsInBody(String url, final ArrayList<Pair<String, String>> params, final Class<T> objectClass) {
StringBuilder postBodyContent = new StringBuilder("");
for (Pair<String, String> p :
params) {
try {
if (postBodyContent.length() != 0)
postBodyContent.append('&');
postBodyContent.append(URLEncoder.encode(p.first, "UTF-8"));
postBodyContent.append("=");
postBodyContent.append(URLEncoder.encode(p.second, "UTF-8"));
} catch (Exception e) {
}
}
return _Post(url, null, postBodyContent.toString(), "application/x-www-form-urlencoded", objectClass);
}
public <T> T Get(String url, final ArrayList<Pair<String, String>> params, final Class<T> objectClass) {
T r = null;
HttpURLConnection connection = null;
try {
connection = _CreateConnection(url, params);
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Accept-Encoding", "gzip");
connection.setDoInput(true);
connection.setUseCaches(false);
connection.connect();
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
if (connection.getHeaderField("Content-Encoding").equalsIgnoreCase("gzip")) {
inputStream = new GZIPInputStream(inputStream);
}
String resultString = _ConvertStreamToString(inputStream);
inputStream.close();
r = AppConstants.Gson_Get().fromJson(resultString, objectClass);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
if (connection != null)
connection.disconnect();
return r;
}
public boolean Delete(String url, final ArrayList<Pair<String, String>> params) {
boolean r = false;
HttpURLConnection connection = null;
try {
connection = _CreateConnection(url, params);
connection.setRequestMethod("DELETE");
connection.setDoInput(true);
connection.connect();
r = connection.getResponseCode() == HttpURLConnection.HTTP_NO_CONTENT;
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
if (connection != null)
connection.disconnect();
return r;
}
public <T, Y> Y InvokeApi(String apiName, final T arg, Class<Y> returnClass) {
return Post(String.format("/api/%s", apiName), arg, returnClass);
}
public <T, Y> void InvokeApiAsync(final String apiName, final T arg, final Class<Y> returnClass, final ActionListener<Y> listener) {
new AsyncTask<Void, Void, Y>() {
#Override
protected Y doInBackground(Void... params) {
return InvokeApi(apiName, arg, returnClass);
}
#Override
protected void onPostExecute(Y result) {
if (listener != null) {
listener.Action(result);
}
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
When I call InvokeApiAsync it takes long time about 3 minutes to get response because of .getoutputstream(). I've been using AsyncTask for parallel connection too.I dont know what to do anymore I will be grateful for any help.
I had this problem before, check your network (perhaps WiFi) proxy on your device that you test your code on!
Android tries to connect to the proxy and if it fails (incorrect proxy or very slow one) it will wait for a long time (default) to get the outputStream.
Either turn the proxy off or set the time out to smaller value to get the timeout exception sooner!
You had better use an IntentService instead of AsyncTask for API connections.
In here the code with BufferedReaderand line = reader.readLine() works
public class WeatherService extends AsyncTask<TaskParams, Void, String> {
private WeatherServiceCallback callback;
private Exception exception;
public WeatherService(WeatherServiceCallback callback) {
this.callback = callback;
}
#Override
protected String doInBackground(TaskParams... params) {
try {
URL url = new URL("http://api.openweathermap.org/data/2.5/weather?lat=" +
params[0].getLat() + "&lon=" + params[0].getLon() +
"&units=" + TaskParams.getUnits() +
"&type=" + TaskParams.getAccuracy() + "&lang=" + TaskParams.getLanguage() +
"&appid=10660a09a9fb335d72f576f7aa1bbe5b");
URLConnection connection = url.openConnection();
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder builder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
return builder.toString();
} catch (MalformedURLException e) {
exception = e;
} catch (IOException e) {
exception = e;
}
return null;
}
#Override
protected void onPostExecute(String s)
{
if (s == null && exception != null)
{
callback.serviceFailure(exception);
return;
}
try
{
JSONObject data = new JSONObject(s);
Parameters parameters = new Parameters();
parameters.poopulate(data);
callback.serviceSuccess(parameters);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
I copy-pasted code to other class since it has very similar functionality and now for no reason I'm getting NullPointerException in while ((line = reader.readLine()) != null) and I have no idea why since as I said it's copy-pasted (I only changed URL and object returned if serivce succeeds)
public class PollutionService extends AsyncTask<TaskParams, Void, String>
{
private PollutionServiceCallback callback;
private Exception exception;
private URLConnection connection;
private InputStream inputStream;
private InputStreamReader streamReader;
private BufferedReader reader;
public PollutionService(PollutionServiceCallback callback) {
this.callback = callback;
}
#Override
protected String doInBackground(TaskParams... params) {
try
{
URL url = new URL("http://api.openweathermap.org/pollution/v1/co/" + params[0].getLat() +
"," + params[0].getLon() + "/current.json?&appid=10660a09a9fb335d72f576f7aa1bbe5b");
try
{
connection = url.openConnection();
}
catch (IOException e)
{
exception = new Exception("Connection error");
}
try
{
inputStream = connection.getInputStream();
}
catch (IOException e)
{
exception = new Exception("Input stream error");
}
try
{
streamReader = new InputStreamReader(inputStream);
}
catch (NullPointerException e)
{
exception = new Exception("Input stream reader error");
}
try
{
reader = new BufferedReader(streamReader);
}
catch (NullPointerException e)
{
exception = new Exception("Buffered reader error");
}
StringBuilder builder = new StringBuilder();
String line;
try
{
while ((line = reader.readLine()) != null)
{
builder.append(line);
}
}
catch (IOException e)
{
exception = e;
}
return builder.toString();
}
catch (MalformedURLException e)
{
exception = e;
}
return null;
}
#Override
protected void onPostExecute(String s)
{
if (s == null && exception != null)
{
callback.pollutionServiceFailure(exception);
return;
}
try
{
JSONObject data = new JSONObject(s);
PollutionParameters parameters = new PollutionParameters();
parameters.poopulate(data);
callback.pollutionServiceSuccess(parameters);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Any clue?
EDIT
This is rewritten code for PollutionActivity. Callback function serviceFailure prints now the URL address on my phone's screen
public class PollutionService extends AsyncTask<TaskParams, Void, String>
{
private PollutionServiceCallback callback;
private Exception exception;
public PollutionService(PollutionServiceCallback callback) {
this.callback = callback;
}
#Override
protected String doInBackground(TaskParams... params) {
try
{
URL url = new URL("http://api.openweathermap.org/pollution/v1/co/" + params[0].getLat() +
"," + params[0].getLon() + "/current.json?&appid=10660a09a9fb335d72f576f7aa1bbe5b");
URLConnection connection = url.openConnection();
InputStream inputStream = connection.getInputStream();
InputStreamReader streamReader = new InputStreamReader(inputStream);
BufferedReader reader = new BufferedReader(streamReader);
StringBuilder builder = new StringBuilder();
String line;
try
{
while ((line = reader.readLine()) != null)
{
builder.append(line);
}
}
catch (IOException e)
{
exception = e;
}
return builder.toString();
}
catch (MalformedURLException e)
{
exception = e;
}
catch (IOException e)
{
exception = e;
}
return null;
}
#Override
protected void onPostExecute(String s)
{
if (s == null && exception != null)
{
callback.pollutionServiceFailure(exception);
return;
}
try
{
JSONObject data = new JSONObject(s);
PollutionParameters parameters = new PollutionParameters();
parameters.poopulate(data);
callback.pollutionServiceSuccess(parameters);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Debugging showed me that code jumps to exception after
InputStream inputStream = connection.getInputStream();
If you are getting NPE for reader then it means that reader is not getting initialized and going null.Your code is getting crash at line 23 and 89. So I believe that the problem is right at the start somewhere and not at the point itself, may be some object is going null like connection.Since line number is not displayed here.Check null pointer for every object like if (connection!=null). Since the initial data is coming null,maybe input stream or some other data,hence your reader object is not getting initialized.Also check if you are getting value for every object in debug.
I have a problem. I met only once. My code algoritm is designed requesting only one time.
But a request was received twice by server. I must produce a solution.
I think, this problem likes this url But I cant find anything(bug or question) about httpurlconnection?
Device's Android Version is 4.0.3 and Connection Method is GET.
try {
String encoding = session.getPlatform().getEncodingIse();
if (TradeUtil.isApachiClientActive()) {
HttpResponse hr = XHttpClientFactory.getConnectionResponse(session.getPlatform(), TradeServiceType.ISE, command);
if (!session.getPlatform().isUseStaticEncodingForIse()) {
encoding = XHttpClientFactory.getEncoding(hr, encoding);
}
strRtn = TradeUtil.getResponse(hr.getEntity().getContent(), encoding);
} else {
con = TradeUtil.createConnection(session.getPlatform(), TradeServiceType.ISE, command);
if (!session.getPlatform().isUseStaticEncodingForIse()) {
encoding = TradeUtil.getEncoding(con, session.getPlatform().getEncodingIse());
}
strRtn = TradeUtil.getResponse(con.getInputStream(), encoding);
}
} catch (Exception e) {
TradeUtil.toConsole(e);
response.getResponseResult().setResponseCode(ResponseResult.CONNECTION_ERROR);
response.getResponseResult().setDescription(e.getMessage());
try {
if (con != null)
con.disconnect();
} catch (Exception ex) {
}
return response;
}
public static HttpURLConnection createConnection(Platform platform,
TradeServiceType serviceType, String command) throws Exception {
command = command + "&MTXTimeAnd=" + Calendar.getInstance().getTimeInMillis(); // Cachlemeyi
// Engellemek
// için
TradeUtil.initSSLContext(); // Zoom ve ustundeki makinalar için SSL
// handshake için trust manager set etmek
// gerekiyor.
System.setProperty("http.keepAlive", "false");// Yatirim finansman +
// Android 2.2 Bug için
// gerekli
System.setProperty("https.keepAlive", "false"); // Yatirim finansman +
// Android 2.2 Bug için
// gerekli
HttpURLConnection con;
String methodType;
String encoding;
String strAdd = null;
if (serviceType.equals(TradeServiceType.ISE)) {
strAdd = platform.getIseServiceAdress();
methodType = platform.getIseConnectionMethodType();
encoding = platform.getEncodingIse();
} else if (serviceType.equals(TradeServiceType.TURKDEX)) {
strAdd = platform.getTurkdexServiceAdress();
methodType = platform.getTurkdexConnectionMethodType();
encoding = platform.getEncodingTurkdex();
} else {
throw new IllegalArgumentException("hatali service tipi");
}
if (methodType.equalsIgnoreCase("GET")) {
strAdd = strAdd + "?" + command;
}
URL adress = new URL(strAdd);
if (adress.getProtocol().equalsIgnoreCase("https")) {
con = (HttpsURLConnection) adress.openConnection();
((HttpsURLConnection) con).setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
} else {
con = (HttpURLConnection) adress.openConnection();
}
con.setUseCaches(false);
con.setReadTimeout(platform.getConnectionTimeout());
con.setConnectTimeout(platform.getConnectionTimeout());
if (methodType.equalsIgnoreCase("POST")) {
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestMethod("POST");
OutputStreamWriter osw = null;
try {
osw = new OutputStreamWriter(con.getOutputStream(), encoding);
osw.write(command);
osw.flush();
osw.close();
osw = null;
} catch (Exception ex) {
TradeUtil.toConsole(ex);
try {
if (osw != null)
osw.close();
} catch (Exception ex2) {
TradeUtil.toConsole(ex);
}
throw ex;
}
} else {
}
return con;
}