I've been trying to figure this out on my own for quite a while.. by trial/error as well as research, but I just can't seem to get it figured out. I'm pretty bad with Async and network connections and stuch, so it might be something simple that I'm over looking. Anyway... I'll paste some relevant code samples and explanations.
Quick background of my problem. I'm working with the Rotten Tomatoes API for my app, and am using GSON for the parsing of their data. I was initially targeting 2.3, and this worked fine. Then I decided to have support for ICS, and of course ran into the "no network operation on the UI thread" - so I started to delve into AsyncTask.
Here is my InputStream method:
private InputStream retrieveStream(String url) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet getRequest = new HttpGet(url);
try {
HttpResponse getResponse = client.execute(getRequest);
final int statusCode = getResponse.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w(getClass().getSimpleName(),
"Error " + statusCode + " for URL " + url);
return null;
}
HttpEntity getResponseEntity = getResponse.getEntity();
return getResponseEntity.getContent();
}
catch (IOException e) {
getRequest.abort();
Log.w(getClass().getSimpleName(), "Error for URL " + url, e);
}
return null;
}
InputStream source = retrieveStream( url parameter );
private PerformMovieSearch performSearch = new PerformMovieSearch(this);
InputStream source = performSearch.retrieveStream(movieQueryUrl);
package net.neonlotus.ucritic;
[imports]
public class PerformMovieSearch extends AsyncTask<String, Void, String> {
private final Context context;
private ProgressDialog progressDialog;
public PerformMovieSearch(Context context){
this.context = context;
}
@Override
protected String doInBackground(String... urls) {
retrieveStream(urls[0]);
return null;
}
@Override
protected void onPreExecute() {
progressDialog= ProgressDialog.show(context, "Please Wait","Searching movies", true);
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
progressDialog.dismiss();
MyActivity.mListAdapter.notifyDataSetChanged();
}
public InputStream retrieveStream(String url) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet getRequest = new HttpGet(url);
try {
HttpResponse getResponse = client.execute(getRequest);
final int statusCode = getResponse.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w(getClass().getSimpleName(),
"Error " + statusCode + " for URL " + url);
return null;
}
HttpEntity getResponseEntity = getResponse.getEntity();
return getResponseEntity.getContent();
} catch (IOException e) {
getRequest.abort();
Log.w(getClass().getSimpleName(), "Error for URL " + url, e);
}
return null;
}
new PerformMovieSearch(this).execute(movieQueryUrl);
the point is, you didn't understand how asynctask works!
You MUST read the guide Processes and Threads: http://developer.android.com/guide/components/processes-and-threads.html
But ok, let me try help you.
On doInBackground you are correctly calling the method retrieveStream, but you are doing nothing with the stream. So, you have to process the stream and then, return it. As you said you are expecting an JSON, I'm assuming you will receive a String, so the code of your retrieveStream should like this:
public String retrieveStream(String url) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet getRequest = new HttpGet(url);
try {
HttpResponse getResponse = client.execute(getRequest);
final int statusCode = getResponse.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w(getClass().getSimpleName(),
"Error " + statusCode + " for URL " + url);
return null;
}
HttpEntity getResponseEntity = getResponse.getEntity();
String jsonString = EntityUtils.toString(getResponseEntity);
return jsonString;
} catch (IOException e) {
getRequest.abort();
Log.w(getClass().getSimpleName(), "Error for URL " + url, e);
}
return null;
}
Look that I changed the return type to String. And maybe, you should change the name to retrieveMoviesJSON or something like this.
And you should change your AsyncTask to something like this:
class PerformMovieSearch AsyncTask<String, Void, ArrayList<Movie>>() {
@Override
protected void onPreExecute() {
progressDialog= ProgressDialog.show(context, "Please Wait","Searching movies", true);
}
@Override
protected ArrayList<Movie> doInBackground(String... params) {
String moviesJson = retrieveStream[params[0]];
JSONObject moviesJson = new JSONObject(moviesJson);
ArrayList<Movie> movies = new ArrayList<Movie>();
/*
* Do your code to process the JSON and create an ArrayList of films.
* It's just a suggestion how to store the data.
*/
return movies;
}
protected void onPostExecute(ArrayList<Movie> result) {
progressDialog.dismiss();
//create a method to set an ArrayList in your adapter and set it here.
MyActivity.mListAdapter.setMovies(result);
MyActivity.mListAdapter.notifyDataSetChanged();
}
}
And you can call as the same way you were doing.
Is it clear? Need more explanation?
[]s Neto