Tuesday, March 20, 2012

HttpClient vs HttpUrlConnection (Part 1/2)

In Android there are two basic packages to use to access HTTP connections.  One is HttpClient which is easy to use and most examples on the internet follow this example, however I see many comment indicating it is deprecated.  HttpUrlConnection requires more configuration and is harder to understand, but appears to be the future for Android.

So far my app uses the HttpClient connection, but now that I need to upload files I've found more examples for HttpUrlConnection examples that are able to chunk files up and send them.  Also with HttpClient I've have the code in place to keep authentication cookies for long-lived sessions, and handle various timeouts.
So is it worth spending hours converting my app to a HttpUrlConnection or use the MultipartEntity class in HttpClient?

<code>

/**
 * Use a singleton to hold basic to be used across the app
 * HttpClient Connection is set here so that while the app is active the session is
 * maintained
 * @author sbossen
 */

public class BaseAppData extends Application {
        private static BaseAppData singleton;
        private static HttpClient client;
public static int TIMEOUT_CONNECTION_MS = 5000;
public static int TIMEOUT_SOCKET_MS = 10000; //5000 too slow, changed to 10000
public static long TIMEOUT_CONNECTION_MGR_MS = 5000;



public static BaseAppData getInstance() {
return singleton;
}

/**
       * Creates an HttpClient object if one does not exist or reuse it if already created
       * @return HttpClient
       */
public static HttpClient getHttpClient() {
if (client == null) {
HttpParams httpParameters = new BasicHttpParams();
//set HTTP protocol to 1.1 to avoid possible delays on posting
HttpProtocolParams.setVersion(httpParameters, HttpVersion.HTTP_1_1);
// Set the timeout in milliseconds until a connection is established.
// The default value is zero, that means the timeout is not used.
HttpConnectionParams.setConnectionTimeout(httpParameters, TIMEOUT_CONNECTION_MS);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
HttpConnectionParams.setSoTimeout(httpParameters, TIMEOUT_SOCKET_MS);
httpParameters.setLongParameter(ConnManagerPNames.TIMEOUT, TIMEOUT_CONNECTION_MGR_MS);
client = new DefaultHttpClient(httpParameters);
}
return client;
}


/**
* If a socket timeout is detected while connecting, reset the client by setting it to null here
* to regenerate the connection.  Otherwise a bad connection could be maintained for a while
* @param new_http_client
*/
public static void setHttpClient(HttpClient new_http_client) {


BaseAppData.client = new_http_client;
}


}

</code>

HttpClient code - modified from: octagon (http://groups.google.com/group/android-developers/browse_thread/thread/dcaf8b2fdd8a90c4/62d5e2ffef31ebdb)
<code>

/**
     * Upload a file using a HttpClient POST request.
     * @param client the HTTP client object
     * @param filePath local file location
     * @param uploadUri URI to POST to
     * @param inputNameAttr the name attribute of the file input
element in
     * the html form
     * @throws IOException
     * @throws ClientProtocolException
     */
    public void httpPostFileUpload( HttpClient client, String filePath, String uploadUri,
                String inputNameAttr) throws ClientProtocolException,
IOException {
        HttpUriRequest  request         = new HttpPost(uploadUri);
        MultipartEntity form            = new MultipartEntity();
        //add file to the request
        form.addPart(inputNameAttr, new FileBody(new File(filePath)));
        //execute the request
        ((HttpEntityEnclosingRequestBase) request).setEntity(form);
         try {
                        client.execute(request);
         } catch (ClientProtocolException e) {
                        throw e;
         } catch (IOException ee) {
                        throw ee;
         }
}
</code>