No more playing with AndroidHttpClient
authorgumartinm <gu.martinm@gmail.com>
Tue, 31 Jan 2012 06:33:23 +0000 (07:33 +0100)
committergumartinm <gu.martinm@gmail.com>
Tue, 31 Jan 2012 06:33:23 +0000 (07:33 +0100)
Next step: sqlite Android database.

Android/Testing/Test3/src/de/android/test3/MobieAdHttpClient.java [new file with mode: 0644]
Android/Testing/Test3/src/de/android/test3/NextActivity.java

diff --git a/Android/Testing/Test3/src/de/android/test3/MobieAdHttpClient.java b/Android/Testing/Test3/src/de/android/test3/MobieAdHttpClient.java
new file mode 100644 (file)
index 0000000..369d809
--- /dev/null
@@ -0,0 +1,209 @@
+package de.android.test3;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Random;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.methods.HttpGet;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+import android.net.http.AndroidHttpClient;
+import android.util.Log;
+
+public class MobieAdHttpClient implements Runnable 
+{
+          private static final String VALIDCHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+          private final String cookie;
+          private static final String TAG = "MobieAdHttpClient";
+          private final Random random = new Random();
+          private final URL url;
+          private final AndroidHttpClient httpClient;
+        
+          public MobieAdHttpClient(final String cookie, final URL url, final AndroidHttpClient httpClient) {
+               this.cookie = cookie;
+               this.url = url;
+               this.httpClient = httpClient;
+          }
+          
+          @Override
+          public void run()
+          {
+                  ResponseHandler<StringBuilder> handler = new ResponseHandler<StringBuilder>() {
+                           public StringBuilder handleResponse(HttpResponse response) 
+                                       throws ClientProtocolException, UnsupportedEncodingException, IllegalStateException, IOException {
+                               //There could be a null as return value in case of not receiving any data from the server, 
+                               //although the HTTP connection was OK.
+                               return sortResponse(response);
+                           }
+                       };
+                       
+                  try {
+                          final HttpGet httpGet = new HttpGet();                          
+                          
+                          httpGet.setHeader("Cookie", this.cookie);
+                          try {
+                                  httpGet.setURI(url.toURI()); 
+                                  //http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html
+                                  //2.9. Multithreaded request execution
+                                  //When equipped with a pooling connection manager such as ThreadSafeClientConnManager, 
+                                  //HttpClient can be used to execute multiple requests simultaneously using multiple threads of execution.
+                                  //The ThreadSafeClientConnManager will allocate connections based on its configuration. 
+                                  //If all connections for a given route have already been leased, a request for a connection 
+                                  //will block until a connection is released back to the pool. One can ensure the connection manager does 
+                                  //not block indefinitely in the connection request operation by setting 'http.conn-manager.timeout' to a 
+                                  //positive value. If the connection request cannot be serviced within the given time period 
+                                  //ConnectionPoolTimeoutException will be thrown.
+                                  //CoreConnectionPNames.CONNECTION_TIMEOUT='http.connection.timeout':  determines the timeout in milliseconds 
+                                  //until a connection is established. A timeout value of zero is interpreted as an infinite timeout. 
+                                  //This parameter expects a value of type java.lang.Integer. If this parameter is not set, connect 
+                                  //operations will not time out (infinite timeout).
+                                  
+                                  //2.11. Connection keep alive strategy
+                                  //The HTTP specification does not specify how long a persistent connection may be and should be kept alive. 
+                                  //Some HTTP servers use a non-standard Keep-Alive header to communicate to the client the period of time in 
+                                  //seconds they intend to keep the connection alive on the server side. HttpClient makes use of this information 
+                                  //if available. If the Keep-Alive header is not present in the response, HttpClient assumes the connection can 
+                                  //be kept alive indefinitely. However, many HTTP servers in general use are configured to drop persistent connections 
+                                  //after a certain period of inactivity in order to conserve system resources, quite often without informing the client. 
+                                  //In case the default strategy turns out to be too optimistic, one may want to provide a custom keep-alive strategy.
+                                          
+                                  //So AndroidHttpClient infinite timeout
+                                  //and the connection can be kept forever.
+                                  StringBuilder builder = httpClient.execute(httpGet, handler);
+                                  if (builder != null) {
+                                          JSONTokener tokener = new JSONTokener(builder.toString());
+                                          JSONArray finalResult = new JSONArray(tokener);
+                                          for (int i = 0; i < finalResult.length(); i++) {
+                                                  JSONObject objects = finalResult.getJSONObject(i);
+                                                  //Find out if that id is in the SQLITE database.
+                                                  downloadAds((Integer) objects.get("id"), (String)objects.get("domain"), (String)objects.get("link"));   
+                                          }    
+                                  }  
+                          } catch (URISyntaxException e) {
+                                  Log.e(TAG, "Error while creating URI from URL.", e);  
+                          } catch (ClientProtocolException e) {
+                                  Log.e(TAG, "Error while executing HTTP client connection.", e);
+                          } catch (UnsupportedEncodingException e)  {
+                                  Log.e(TAG, "Error  InputStreamReader.", e);
+                          } catch (IOException e) {
+                                  Log.e(TAG, "Error while executing HTTP client connection.", e);
+                          } catch (JSONException e) {
+                                  Log.e(TAG, "Error while parsing JSON response.", e); 
+                          } finally {
+                                  //Always release the resources whatever happens. Even when there is an 
+                                  //unchecked exception which (by the way) is not expected. Be ready for the worse.
+                                  //NextActivity.this.httpClient.close();
+                          }   
+                  } catch (Throwable e) {
+                          Log.e(TAG, "Caught exception, something went wrong", e);
+                  }
+          }
+          
+          public StringBuilder sortResponse(HttpResponse httpResponse) throws UnsupportedEncodingException, IllegalStateException, IOException {
+                  StringBuilder builder = null;
+                  
+                  if (httpResponse != null) {
+                          switch (httpResponse.getStatusLine().getStatusCode()) {
+                          case HttpStatus.SC_OK:
+                                  //OK
+                                  HttpEntity entity = httpResponse.getEntity();
+                                  if (entity != null) {
+                                          //outside try/catch block. 
+                                          //In case of exception it is thrown, otherwise instream will not be null and we get into the try/catch block.
+                                          InputStreamReader instream = new InputStreamReader(entity.getContent()/*, entity.getContentEncoding().getValue()*/);
+                                          try {
+                                                  BufferedReader reader = new BufferedReader(instream);                                
+                                                  builder = new StringBuilder();
+                                                  String currentLine = null;
+                                                  currentLine = reader.readLine();
+                                                  while (currentLine != null) {
+                                                          builder.append(currentLine).append("\n");
+                                                          currentLine = reader.readLine();
+                                                  }
+                                          } finally {
+                                                  //instream will never be null in case of reaching this code, cause it was initialized outside try/catch block.
+                                                  //In case of exception here, it is thrown to the superior layer.
+                                                  instream.close();    
+                                          }                            
+                                  }
+                                  break;                               
+                          case HttpStatus.SC_UNAUTHORIZED:
+                                  //ERROR IN USERNAME OR PASSWORD
+                                  break;                               
+                          case HttpStatus.SC_BAD_REQUEST:
+                                  //WHAT THE HECK ARE YOU DOING?
+                                  break;                               
+                          default:
+                                  Log.e(TAG, "Error while retrieving the HTTP status line.");
+                                  break;       
+                          }   
+                  }
+                  
+                  return builder;
+          }
+          
+          public void downloadAds(Integer id, String domain, String link) {
+                  //if the id is not on the data base, download the ad, otherwise do nothing. USE synchronize
+                  
+                  final HttpGet httpGet = new HttpGet();
+                  final String URLAd = "http://" + domain + "/" + link;
+                  HttpResponse httpResponse = null;
+                  URL url = null;
+                  OutputStream outputStream = null;
+                  
+                  try {
+                          url = new URL(URLAd);
+                          httpGet.setURI(url.toURI());
+                          //By default max 2 connections at the same time per host.
+                          //and infinite time out (we could wait here forever...)
+                          httpResponse = this.httpClient.execute(httpGet);
+                          outputStream = new FileOutputStream(generateName(this.random, 10));
+                          switch (httpResponse.getStatusLine().getStatusCode()) {
+                          case HttpStatus.SC_OK:
+                                  try {
+                                          httpResponse.getEntity().writeTo(outputStream);
+                                  } catch (IOException e) {
+                                          Log.e(TAG, "Error while writing to file the received ad.", e);
+                                  }
+                                  break;
+                          default:
+                                  Log.e(TAG, "Error while retrieving the HTTP status line in downloadAds method.");
+                                  break;
+                          }
+                  } catch (MalformedURLException e) {
+                          Log.e(TAG, "Error while creating a URL", e);
+                  } catch (URISyntaxException e) {
+                          Log.e(TAG, "Error while creating URI from URL.", e);  
+                  } catch (ClientProtocolException e) {
+                          Log.e(TAG, "Error while executing HTTP client connection.", e);
+                  } catch (FileNotFoundException e) {
+                          Log.e(TAG, "Error while creating new file.", e);
+                  } catch (IOException e) {
+                          Log.e(TAG, "Error while executing HTTP client connection.", e);
+                  }
+                  //if any error, remove from data base the id and the file stored or the chunk stored successfully before the error. USE synchronize
+          }
+          
+          public String generateName (Random random, int length) {
+                  char[] chars = new char[length];
+              for (int i=0; i < length; i++)
+              {
+                   chars[i] = VALIDCHARS.charAt(random.nextInt(VALIDCHARS.length()));
+              }
+              return new String(chars);
+          }
+       }
index 4688332..9b84d2d 100644 (file)
@@ -1,31 +1,11 @@
 package de.android.test3;
 
-import java.io.BufferedReader;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
-import java.net.URISyntaxException;
 import java.net.URL;
-import java.util.Random;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
 import org.apache.http.HttpVersion;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.ResponseHandler;
-import org.apache.http.client.methods.HttpGet;
 import org.apache.http.params.CoreProtocolPNames;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONTokener;
 import android.app.Activity;
 import android.content.Context;
 import android.location.Criteria;
@@ -41,31 +21,32 @@ import android.webkit.CookieSyncManager;
 public class NextActivity extends Activity {
        private static final String TAG = "NextActivity";
        private String myCookie;
-       private static final int tasksMax = 3;
+       private static final int tasksMax = 10;
        //There will never be more than 3 threads at the same moment. New tasks will wait in a queue
        //for available threads in this pool in case of more than tasksMax tasks at the same moment.
-       //We choose this number because of the ThreadSafeClientConnManager Android implementation where
-       //there are just 2 concurrent connections per given route. :S
+       //The ThreadSafeClientConnManager Android implementation has just 2 concurrent connections
+       //per given route. :S So, the 10 threads are going to share the connection manager, in the
+       //the worst situations 8 threads are going to wait for using the AndroidHttpClient.
        private final ExecutorService exec = Executors.newFixedThreadPool(tasksMax);
        private static final String USERAGENT ="MobieAds/1.0";
        private static final String ENCODED = "UTF-8";
        
        
-//     2.8.4. Pooling connection manager
-//
-//     ThreadSafeClientConnManager is a more complex implementation that manages a 
-//     pool of client connections and is able to service connection requests from
-//     multiple execution threads. Connections are pooled on a per route basis. A request for a 
-//     route for which the manager already has a persistent connection available in the pool 
-//     will be serviced by leasing a connection from the pool rather than creating a brand new connection.
-//
-//     ThreadSafeClientConnManager maintains a maximum limit of connections on a per route basis 
-//     and in total. Per default this implementation will create no more than 2 concurrent 
-//     connections per given route and no more 20 connections in total. For many real-world 
-//     applications these limits may prove too constraining, especially if they use HTTP as 
-//     a transport protocol for their services. Connection limits can be adjusted using the 
-//     appropriate HTTP parameters.
-//     WITH THE ANDROID IMPLEMENTATION WE CAN NOT CHANGE THOSE VALUES!!!! :(
+       //2.8.4. Pooling connection manager
+       //
+       //ThreadSafeClientConnManager is a more complex implementation that manages a 
+       //pool of client connections and is able to service connection requests from
+       //multiple execution threads. Connections are pooled on a per route basis. A request for a 
+       //route for which the manager already has a persistent connection available in the pool 
+       //will be serviced by leasing a connection from the pool rather than creating a brand new connection.
+       //
+       //ThreadSafeClientConnManager maintains a maximum limit of connections on a per route basis 
+       //and in total. Per default this implementation will create no more than 2 concurrent 
+       //connections per given route and no more 20 connections in total. For many real-world 
+       //applications these limits may prove too constraining, especially if they use HTTP as 
+       //a transport protocol for their services. Connection limits can be adjusted using the 
+       //appropriate HTTP parameters.
+       //WITH THE ANDROID IMPLEMENTATION WE CAN NOT CHANGE THOSE VALUES!!!! :(
        private final AndroidHttpClient httpClient = AndroidHttpClient.newInstance(USERAGENT);
 
        
@@ -146,173 +127,7 @@ public class NextActivity extends Activity {
                        Log.e(TAG, "Error while creating a URL", e);
                        return;
                }
-               webServiceConnection = new MobieAdHttpClient(this.myCookie, url);
+               webServiceConnection = new MobieAdHttpClient(this.myCookie, url, httpClient);
                this.exec.execute(webServiceConnection);
     }
-   
-   
-   private class MobieAdHttpClient implements Runnable 
-   {
-          private static final String VALIDCHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-          private final String cookie;
-          private static final String TAG = "MobieAdHttpClient";
-          private final Random random = new Random();
-          private final URL url;
-        
-          public MobieAdHttpClient(final String cookie, final URL url) {
-               this.cookie = cookie;
-               this.url = url;
-          }
-          
-          @Override
-          public void run()
-          {
-                  ResponseHandler<StringBuilder> handler = new ResponseHandler<StringBuilder>() {
-                           public StringBuilder handleResponse(HttpResponse response) 
-                                       throws ClientProtocolException, UnsupportedEncodingException, IllegalStateException, IOException {
-                               //There could be a null as return value in case of not receiving any data from the server, 
-                               //although the HTTP connection was OK.
-                               return sortResponse(response);
-                           }
-                       };
-                       
-                  try {
-                          final HttpGet httpGet = new HttpGet();                          
-                          
-                          httpGet.setHeader("Cookie", this.cookie);
-                          try {
-                                  httpGet.setURI(url.toURI()); 
-//                                http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html
-//                                2.9. Multithreaded request execution
-//                                When equipped with a pooling connection manager such as ThreadSafeClientConnManager, 
-//                                HttpClient can be used to execute multiple requests simultaneously using multiple threads of execution.
-//                                The ThreadSafeClientConnManager will allocate connections based on its configuration. 
-//                                If all connections for a given route have already been leased, a request for a connection 
-//                                will block until a connection is released back to the pool. One can ensure the connection manager does 
-//                                not block indefinitely in the connection request operation by setting 'http.conn-manager.timeout' to a 
-//                                positive value. If the connection request cannot be serviced within the given time period 
-//                                ConnectionPoolTimeoutException will be thrown.
-                                  Log.e(TAG, "Entrada" + Thread.currentThread().getId() + " " + Thread.currentThread().getName());
-                                  StringBuilder builder = httpClient.execute(httpGet, handler);
-                                  Log.e(TAG, "Salida" + Thread.currentThread().getId() + " " + Thread.currentThread().getName());
-                                  if (builder != null) {
-                                          JSONTokener tokener = new JSONTokener(builder.toString());
-                                          JSONArray finalResult = new JSONArray(tokener);
-                                          for (int i = 0; i < finalResult.length(); i++) {
-                                                  //JSONObject objects = finalResult.getJSONObject(i);
-                                                  //downloadAds((Integer) objects.get("id"), (String)objects.get("domain"), (String)objects.get("link"));   
-                                          }    
-                                  }  
-                          } catch (URISyntaxException e) {
-                                  Log.e(TAG, "Error while creating URI from URL.", e);  
-                          } catch (ClientProtocolException e) {
-                                  Log.e(TAG, "Error while executing HTTP client connection.", e);
-                          } catch (UnsupportedEncodingException e)  {
-                                  Log.e(TAG, "Error  InputStreamReader.", e);
-                          } catch (IOException e) {
-                                  Log.e(TAG, "Error while executing HTTP client connection.", e);
-                          } catch (JSONException e) {
-                                  Log.e(TAG, "Error while parsing JSON response.", e); 
-                          } finally {
-                                  //Always release the resources whatever happens. Even when there is an 
-                                  //unchecked exception which (by the way) is not expected. Be ready for the worse.
-                                  //NextActivity.this.httpClient.close();
-                          }   
-                  } catch (Throwable e) {
-                          Log.e(TAG, "Caught exception, something went wrong", e);
-                  }
-          }
-          
-          public StringBuilder sortResponse(HttpResponse httpResponse) throws UnsupportedEncodingException, IllegalStateException, IOException {
-                  StringBuilder builder = null;
-                  
-                  if (httpResponse != null) {
-                          switch (httpResponse.getStatusLine().getStatusCode()) {
-                          case HttpStatus.SC_OK:
-                                  //OK
-                                  HttpEntity entity = httpResponse.getEntity();
-                                  if (entity != null) {
-                                          //outside try/catch block. 
-                                          //In case of exception it is thrown, otherwise instream will not be null and we get into the try/catch block.
-                                          InputStreamReader instream = new InputStreamReader(entity.getContent()/*, entity.getContentEncoding().getValue()*/);
-                                          try {
-                                                  BufferedReader reader = new BufferedReader(instream);                                
-                                                  builder = new StringBuilder();
-                                                  String currentLine = null;
-                                                  currentLine = reader.readLine();
-                                                  while (currentLine != null) {
-                                                          builder.append(currentLine).append("\n");
-                                                          currentLine = reader.readLine();
-                                                  }
-                                          } finally {
-                                                  //instream will never be null in case of reaching this code, cause it was initialized outside try/catch block.
-                                                  //In case of exception here, it is thrown to the superior layer.
-                                                  instream.close();    
-                                          }                            
-                                  }
-                                  break;                               
-                          case HttpStatus.SC_UNAUTHORIZED:
-                                  //ERROR IN USERNAME OR PASSWORD
-                                  break;                               
-                          case HttpStatus.SC_BAD_REQUEST:
-                                  //WHAT THE HECK ARE YOU DOING?
-                                  break;                               
-                          default:
-                                  Log.e(TAG, "Error while retrieving the HTTP status line.");
-                                  break;       
-                          }   
-                  }
-                  
-                  return builder;
-          }
-          
-          public void downloadAds(Integer id, String domain, String link) {
-                  //if the id is not on the data base, download the ad, otherwise do nothing. USE synchronize
-                  
-                  final HttpGet httpGet = new HttpGet();
-                  final String URLAd = "http://" + domain + "/" + link;
-                  HttpResponse httpResponse = null;
-                  URL url = null;
-                  OutputStream outputStream = null;
-                  
-                  try {
-                          url = new URL(URLAd);
-                          httpGet.setURI(url.toURI());  
-                          httpResponse = NextActivity.this.httpClient.execute(httpGet);
-                          outputStream = new FileOutputStream(generateName(this.random, 10));
-                          switch (httpResponse.getStatusLine().getStatusCode()) {
-                          case HttpStatus.SC_OK:
-                                  try {
-                                          httpResponse.getEntity().writeTo(outputStream);
-                                  } catch (IOException e) {
-                                          Log.e(TAG, "Error while writing to file the received ad.", e);
-                                  }
-                                  break;
-                          default:
-                                  Log.e(TAG, "Error while retrieving the HTTP status line in downloadAds method.");
-                                  break;
-                          }
-                  } catch (MalformedURLException e) {
-                          Log.e(TAG, "Error while creating a URL", e);
-                  } catch (URISyntaxException e) {
-                          Log.e(TAG, "Error while creating URI from URL.", e);  
-                  } catch (ClientProtocolException e) {
-                          Log.e(TAG, "Error while executing HTTP client connection.", e);
-                  } catch (FileNotFoundException e) {
-                          Log.e(TAG, "Error while creating new file.", e);
-                  } catch (IOException e) {
-                          Log.e(TAG, "Error while executing HTTP client connection.", e);
-                  }
-                  //if any error, remove from data base the id and the file stored or the chunk stored successfully before the error. USE synchronize
-          }
-          
-          public String generateName (Random random, int length) {
-                  char[] chars = new char[length];
-              for (int i=0; i < length; i++)
-              {
-                   chars[i] = VALIDCHARS.charAt(random.nextInt(VALIDCHARS.length()));
-              }
-              return new String(chars);
-          }
-       }
 }