Best practice to pull content from the web?
<p>I'm new to developing Android applications, and have only a little experience with Java in school. I was redirected to StackOverflow from the Google groups page when I was looking for the Android Beginners group. I have a question about what is best practice to pull content from a web source and parse it.</p>

<p>Firstly, I would eventually like to have my application threaded (by use of Handler?), however, my issue now is that the class I have created (Server) to connect and fetch content often fails to retrieve the content, which causes my JSON parser class (JSONParser) to fail, and my View to display nothing. After navigating to the previous Activity, and attempting to call the connect(), fetch(), and parse() methods on the same remote URI, it will work.</p>

<p>Why does this (sometimes retrieve the remote data) happen <em>sometimes</em>, but not always? What is the best practice, including the use of ProgressDialog and the internal Handler class, to make my application seamless to the user. Is this the best place to ask this question? Thanks for your help</p>

<p>Here is the code I'm using now.</p>

<pre><code>import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import org.apache.http.util.ByteArrayBuffer;

import android.util.Log;

public class Server {

 public static final String HTTP_PROTOCOL = "https://";
 public static final String EXAMPLE_NET_DOMAIN = "example.domain.net/";
 private final String API_KEY = "1234567890";
 private static final String API_ENDPOINT = "api.js?";
 public final String FORMAT = "json";

 public String API_VERSION;
 public String METHOD;
 public String OPTIONAL_ARGUMENTS;

 public String json;
 public URL jURL;
 public URLConnection jConnection;
 public BufferedReader jIn;
    public InputStream is = null;



 /**
  * @param aPIVERSION
  * @param mETHOD
  * @param oPTIONALARGUMENTS
  */
 public Server(String aPIVERSION, String mETHOD, String oPTIONALARGUMENTS) {
  super();
  API_VERSION = aPIVERSION;
  METHOD = mETHOD;
  OPTIONAL_ARGUMENTS = oPTIONALARGUMENTS;

  connect();
  Log.i("DEBUG:","connect();");
 }

 /**
  * @param aPIVERSION
  * @param mETHOD
  */
 public Server(String aPIVERSION, String mETHOD) {
  super();
  API_VERSION = aPIVERSION;
  METHOD = mETHOD;
  OPTIONAL_ARGUMENTS = "";

  connect();
 }

 /**
  * @param aPIVERSION
  * @param mETHOD
  */
 public void connect(){

  try {
         jURL = new URL(HTTP_PROTOCOL 
           + EXAMPLE_NET_DOMAIN 
           + API_ENDPOINT 
           + "api=" + this.API_VERSION 
           + "&amp;method=" + this.METHOD
           + "&amp;format=" + FORMAT
           + "&amp;apikey=" + API_KEY
           + this.OPTIONAL_ARGUMENTS);

         jConnection = jURL.openConnection();

        } catch (IOException e) {

         Log.e("USER: ", "Error in server connection.");
         Log.e("DEBUG:", "Error in server connection");
  }
        Log.i("USER: ", "Connection success!");
 }


 public String fetch() {

  try {
   is = jConnection.getInputStream();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   Log.e("DEBUG:", "fetch-1() error");
  }
      BufferedInputStream bis = new BufferedInputStream(is);
      ByteArrayBuffer baf = new ByteArrayBuffer(50);

     int current = 0;
     try {
   while((current = bis.read()) != -1){
       baf.append((byte)current);
   }
   Log.i("DEBUG:",new String(baf.toByteArray()));

  } catch (IOException e) {
   // TODO Auto-generated catch block
   Log.e("DEBUG:","fetch() ERROR!");
  }

     /* Convert the Bytes read to a String. */
  Log.i("DEBUG:",new String(baf.toByteArray()));
     return new String(baf.toByteArray());

 }

 /* Returns a string containing a concise, human-readable description of jURL
  * 
  */
 public String showUrl() {
  return jURL.toExternalForm();
 }

}
</code></pre>

<p>and the code from my ListActivity</p>

<pre><code>/* Called when the activity is starting. This is where most initialization should go: calling setContentView(int) to inflate the activity's UI, using findViewById(int) to programmatically interact with widgets in the UI, calling managedQuery(android.net.Uri, String[], String, String[], String) to retrieve cursors for data being displayed, etc. 
  * @see android.app.Activity#onCreate()
  */
 @Override
 public void onCreate(Bundle savedInstanceState){
  super.onCreate(savedInstanceState);
  Log.i("LIFECYCLE: ", "RS.class onCreate()");

  Server serverConnection = new Server(API_VERSION, METHOD, OPTIONAL_ARGUMENTS);

     json = serverConnection.fetch();

     JSONParser jParser = new JSONParser(json);

     groupData = jParser.parseJsonForRecentShowList();

     SimpleAdapter adapter = new SimpleAdapter( this, groupData, android.R.layout.simple_list_item_2, new String[] { "venue","showdate"},
                new int[]{ android.R.id.text2, android.R.id.text1 } );
     setListAdapter( adapter );

  registerForContextMenu(getListView());

 }
</code></pre>

<p>Here is my JSON Parser class</p>

<pre><code>/**
 * 
 */

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;


/**
 * @author 
 *
 */
public class JSONParser {

    public List&lt;Map&lt;String, String&gt;&gt; groupData = new ArrayList&lt;Map&lt;String, String&gt;&gt;();

 private String jString;
 private Map&lt;String, String&gt; group;
 private JSONArray jArray;
 private String setlistData;
 public String notesString = "";

 public String[] splitSetsArray;
 public String[] splitEncoreArray;
 public String[] extraWork;
 public String[] notesArray;

 public String pVenue_text;
 public String pCity_text;
 public String pState_text;
 public String pCountry_text;
 public String pDate_text;

 public String pSet1_text;
 public String pSet2_text;
 public String pSet3_text;
 public String pEncore1_text;
 public String pEncore2_text;
 public String pNotes_text;

 public int totalNumberOfSets;
 public int totalNumberOfEncores;
 public int totalNumberOfNotes;

 public JSONObject jObject;


 public JSONParser(String json) {
  // TODO Auto-generated constructor stub
  jString = json;
 }

 /**
  * @return
  */
 public List&lt;Map&lt;String, String&gt;&gt; parseJsonForRecentShowList(){

  try {
   jArray = new JSONArray(jString);

   for(int i=0;i&lt;jArray.length();i++) {
    jObject = jArray.getJSONObject(i);

    group = new HashMap&lt;String, String&gt;();
    group.put("showdate", jObject.getString("showdate"));
    group.put("venue", jObject.getString("venue"));
    groupData.add(group);
   }
  } catch (JSONException e) {
   Log.e("DEBUG: ", "JSON Parse error!");
  }
  return groupData;
 }

 /**
  * 
  */
 public void parseJsonForSetlistData(){
  if(jString != null){
      try {
    jArray = new JSONArray(jString);

    jObject = jArray.getJSONObject(0);

    pVenue_text  = jObject.getString("venue")  ;
    pCity_text   = jObject.getString("city") + ", " ;
    pState_text  = jObject.getString("state") + ", " ;
    pCountry_text  = jObject.getString("country") ;
    pDate_text   = jObject.getString("nicedate")  ;

    setlistData = nohtml(jObject.getString("setlistdata"));

    splitSetsArray = setlistData.split("Set..:.");
       totalNumberOfSets = splitSetsArray.length-1;

       String[] splitEncoreArray = splitSetsArray[splitSetsArray.length-1].split("Encore:.");
       totalNumberOfEncores = splitEncoreArray.length-1;
       splitSetsArray[splitSetsArray.length-1] = splitEncoreArray[0];
       splitEncoreArray[0] = "";

       extraWork = splitEncoreArray[splitEncoreArray.length-1].split("\\[1\\]");

    notesArray = extraWork[extraWork.length-1].split("\\[.\\]");
    totalNumberOfNotes = notesArray.length-1;
    splitEncoreArray[splitEncoreArray.length-1] = extraWork[0];
    //notesArray[0] = "";

    for(int i=0;i&lt;notesArray.length;i++){
     int number = i+1;
     notesString += "["+number+"] "+notesArray[i] + "\n";
    }

    if(totalNumberOfSets != 0) {
     pSet1_text = "Set 1: " + splitSetsArray[1];
     if (totalNumberOfSets &gt; 1){
      pSet2_text = "Set 2: " + splitSetsArray[2];
     } else {
      pSet2_text = "";
     }
     if (totalNumberOfSets &gt; 2){
      pSet3_text = "Set 3: " + splitSetsArray[3];
     } else {
      pSet3_text = "";
     }
    }

    pEncore1_text = "Encore: " + splitEncoreArray[1];
    if (totalNumberOfEncores &gt; 1) {
     pEncore2_text = "Encore 2: " + splitEncoreArray[2];
    } else {
     pEncore2_text = "";
    }
    pNotes_text = notesString;

    Log.e("DEBUG: ", "JSON Parsed!");

   } catch (JSONException e) {

    Log.e("ERROR:","caught JSON Exception at parseForSetlistData()");

   }

  } else {

   Log.e("ERROR:", "jString = null");
   pVenue_text = "I'm Sorry, the Setlist Data could not be retrieved from server. Please try again.";

  }

    }

    public void parseJsonForReviews(){
  try {
   jArray = new JSONArray(jString);

   for(int i=0;i&lt;jArray.length();i++){
    jObject = jArray.getJSONObject(i);

    group = new HashMap&lt;String, String&gt;();
    group.put("author", jObject.getString("author"));
    group.put("review", jObject.getString("review"));
    groupData.add(group);
    }
  } catch (JSONException e) {
   Log.e("DEBUG: ", "JSON Reviews parse error!");
  }

    }

    public List&lt;Map&lt;String, String&gt;&gt; parseJsonForYears(){
  try {
   jArray = new JSONArray(jString);

   for(int i=0;i&lt;jArray.length();i++){
    JSONObject jObject = jArray.getJSONObject(i);
    group = new HashMap&lt;String, String&gt;();
    group.put("showdate", jObject.getString("showdate"));
    group.put("venue", jObject.getString("venue"));
    groupData.add(group);
   }
  } catch (JSONException e) {
   Log.e("DEBUG: ", "JSON Years parse error!");
  }

  Collections.reverse(groupData);

  return groupData;
    }

    public String nohtml(String json){
     return json.toString().replaceAll("\\&lt;.*?&gt;", "");
    }

}
</code></pre>
