W mojej aplikacji na Androida próbuję pobrać dane z serwera, wykonując żądanie POST.getHttpResponseCode() zwraca -1 w systemie Android 2.2
Używam klasy HttpURLConnection
do wysyłania żądań jako serwer Apache HttpClient
, który nie jest już obsługiwany przez Androida.
Oto, co robię.
private boolean callWS() {
try {
// To avoid the bug in httpurlconnection prior froyo which
// causes the getInputStream to return headers along with response
if (Build.VERSION.SDK_INT < 8)
System.setProperty("http.keepAlive", "false");
mHttpResponseCode = 0;
mErrorMessage = "";
// Initialize connection
URL connectURL = new URL(mServerUrl);
HttpURLConnection conn = (HttpURLConnection) connectURL.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setInstanceFollowRedirects(true);
conn.setReadTimeout(30000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
// Set some headers
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Accept-Encoding", "deflate, gzip");
connection.setRequestProperty("Content-Length", mParameters.length() + "");
// Connect to host
conn.connect();
// Write parameters to connection
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(mParameters);
writer.flush();
writer.close();
// Wait for http response code
mHttpResponseCode = conn.getResponseCode();
// Read response from connection
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int read = 0;
int bufSize = 1024;
byte[] buffer = new byte[bufSize];
while (true) {
read = bis.read(buffer);
if (read == -1)
break;
baf.append(buffer, 0, read);
}
// Decompress gzipped response
if (conn.getHeaderField("Content-Encoding") != null && conn.getHeaderField("Content-Encoding").contains("gzip"))
mResponseString = decompress(baf.toByteArray());
else
mResponseString = new String(baf.toByteArray());
mResponse.setResponse(mResponseString);
isWSCallSuccessfull = true;
} catch(UnknownHostException unknownHostException) {
isWSCallSuccessfull = false;
mErrorMessage = "Unknown host exception";
unknownHostException.printStackTrace();
mLogger.putStacktrace(unknownHostException);
} catch(SocketException socketException) {
isWSCallSuccessfull = false;
mErrorMessage = "Socket Exception";
socketException.printStackTrace();
mLogger.putStacktrace(socketException);
} catch(SocketTimeoutException socketTimeOutException) {
isWSCallSuccessfull = false;
mErrorMessage = "Socket Timeout Exception";
socketTimeOutException.printStackTrace();
mLogger.putStacktrace(socketTimeOutException);
} catch(SSLException sslException) {
isWSCallSuccessfull = false;
mErrorMessage = "SSL Exception";
sslException.printStackTrace();
mLogger.putStacktrace(sslException);
} catch(IOException ioException) {
isWSCallSuccessfull = false;
mErrorMessage = "IO Exception " + ioException.getMessage();
ioException.printStackTrace();
mLogger.putStacktrace(ioException);
}
mResponse.setHttpResponseCode(mHttpResponseCode);
mResponse.setErrorMessage(mErrorMessage);
mResponse.isWSCallSuccessful(isWSCallSuccessfull);
return isWSCallSuccessfull;
}
Działa to dobrze na każdym urządzeniu, z wyjątkiem urządzeń z systemem 2.2 (nie spróbować go na 2,1).
W wersji 2.2 działa poprawnie. Ale jeśli zostawiam tę część kodu bezczynnego przez ponad 30 sekund, zwraca ona ponownie -1 jako kod odpowiedzi http zaraz po następnym.
Inną rzeczą, na którą należy zwrócić uwagę, jest to, że dzieje się tak tylko z adresami URL HTTPS, a nie z adresami URL HTTP. Nie chcę używać klasy HttpsURLConnection, ponieważ czasami mogę chcieć również użyć http.
Nie zamykam połączenia tylko po to, aby utrzymać połączenie przy życiu. Co ja robię źle?
czy połączenia Https automatycznie się zamykają po pewnym czasie (jeśli nic nie jest przenoszone, mam na myśli)? Nie wiem zbyt wiele o połączeniach https, więc może to być całkowicie błędne. (Odczytywanie go z powrotem Nie jestem nawet pewien, co powiedziałem ma sens LOL) –
-1 jest zwykle, gdy połączenie nie powiodło się z powodu, który nie jest określony przez kod HTTP - w twoim przypadku brzmi to jak timeout, ale może również być nieudolnym rozpoznawaniem DNS, itd ... Teraz, kiedy _ konkretna wersja Androida kończy się, nie wiem ... – Basic
Cóż, mój pomysł polega na tym, że jeśli nie robię niczego złego, to jest tylko ten problem ze mną? Ponieważ przeszukując w sieci, nie znalazłem nikogo, kto miałby ten problem. – Enigma