How to get a string back from AsyncTask?
I have the following class:
public class getURLData extends AsyncTask<String, Integer, String>{
@Override
protected String doInBackground(String... params) {
String line;
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(params[0]);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
line = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
line = "<results status=\"error\"><msg>Can't connect to server</msg></results>";
} catch (MalformedURLException e) {
line = "<results status=\"error\"><msg>Can't connect to server</msg></results>";
} catch (IOException e) {
line = "<results status=\"error\"><msg>Can't connect to server</msg></results>";
}
return line;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
And I am trying to call it like this:
String output = null;
output = new getURLData().execute("http://www.domain.com/call.php?locationSearched=" + locationSearched);
But the output variable isn't getting data, instead I am getting an error:
Type mismatch: cannot convert from AsyncTask<String,Integer,String> to String
Solution 1:
The method execute
returns the AynscTask
itself, you need to call get
:
output =
new getURLData()
.execute("http://www.example.com/call.php?locationSearched=" + locationSearched)
.get();
This will start a new thread (via execute
) while blocking the current thread (via get
) until the work from the new thread has been finished and the result has been returned.
If you do this, you just turned your async task into a sync one.
However, the problem with using get
is that because it blocks, it needs to be called on a worker thread. However, AsyncTask.execute()
needs to be called on the main thread. So although this code could work, you may get some undesired results. I also suspect that get()
is under-tested by Google, and it is possible that they introduced a bug somewhere along the line.
Reference: AsyncTask.get
Solution 2:
I'd rather create callback than block UI thread. In your class create method which will be invoked when data arrive. For example:
private void setData(String data){
mTextView.setText(data);
}
Then in AsyncTask implement onPostExecute:
@Override
protected void onPostExecute(String result) {
setData(result);
}
And then somewhere in code just execute task:
new getURLData().execute(...
When task finishes setData is invoked and mTextView is filled.
AsyncTask.get() will blok your UI, so there is no reason to use AsyncTask.