Reputation: 23
We have a problem getting HttpASyncTask to return a String from our simple http function: Simply we want to be able to send data to a URL and receive a proper response we can use later in our other classes. The httphandler class does receive the right response up until a point.
Here is our httphandler:
public class HttpRequester extends Activity {
static String result;
public String createUser(String username) {
new HttpAsyncTask().execute("http://188.226.252.112/createPlayer.php?name=" + username);
System.out.println("ID at createUser is; " + result); // this also returns null
return result;
}
public static String GET(String url){
InputStream inputStream = null;
try {
// create HttpClient
HttpClient httpclient = new DefaultHttpClient();
// make GET request to the given URL
HttpResponse httpResponse = httpclient.execute(new HttpGet(url));
// receive response as inputStream
inputStream = httpResponse.getEntity().getContent();
// convert inputstream to string
if(inputStream != null)
result = convertInputStreamToString(inputStream);
else
result = "Did not work!";
} catch (Exception e) {
Log.d("InputStream", e.getLocalizedMessage());
}
System.out.println("ID at GET is; " + result); // this returns correct ID
return result;
}
private static String convertInputStreamToString(InputStream inputStream) throws IOException{
StringBuilder sb = new StringBuilder();
String something;
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream));
while ((something = bufferedReader.readLine()) != null) {
sb.append(something);
}
inputStream.close();
result = sb.toString();
System.out.println("ID at convert is; " + result); // this returns correct ID
return result;
}
public boolean isConnected(){
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(this.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected())
return true;
else
return false;
}
private class HttpAsyncTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... urls) {
return GET(urls[0]);
}
}
}
And here is the other class' function which has to receive the data from the http handler:
HttpRequester requester = new HttpRequester();
ID = requester.createUser(login);
System.out.println("ID in other class is: " + ID); // this returns null
Please help
Regards
Cong Vinh
Upvotes: 2
Views: 180
Reputation: 2591
Your approach is incorrect. When you call new HttpAsyncTask().execute()
this starts a new asynchronous operation (a new thread is spawn under the hood). The execute
method returns immediately and the result
property stays null. This is why the createUser
method returns null. The GET
method is synchronous. In the context of your program it is executed in a separate thread (the thread started from the HttpAsyncTask
) but all methods in it are executed consistently. This is why the result
property here is initialized and holds the correct result.
result
property) between different threads. This can be the root of serious concurrent problems. The better approach is to keep this property part of the HttpAsyncTask
class and return it as a result of the AsyncTask
execution.postExecuted
method of the HttpAsyncTask
class (that is not implemented here but can be overridden). This is the only correct way that you can be sure that the processing will be executed after the HTTP call has been made and the result has been received.Upvotes: 2