Reputation: 71
I'm trying to resolve this problem: I have a class that extends from AsyncTask, that execute some http methods, something like this:
public class RESTManager extends AsyncTask<Object, Object, String>
{
public RESTManager(String url, MethodTypes myMethod,ICallbackHandler hndl, String restMethod)
{
initialize();
}
private String doGET()
{
}
private String doPOST()
{
}
@Override
protected String doInBackground(Object... params)
{
}
@Override
protected void onPostExecute(String result)
{
}
}
So, from Activity I' doing this:
RESTManager webService = new WSManager(URL, MethodTypes.REGISTER, params, this, WSManager.GET_METHOD);
webService.execute();
And then the activity receives the response in the callbak method (because activity implements this interface):
public void response(String response)
{
// some process
}
This is working ok, but my problem is that I would like that the answer comes in the same call to some function, and then that function calls the .execute method, for example.
// This is a new class
public class MyWebServices()
{
public User getUser(int id)
{
User myUser;
RESTManager webService = new WSManager(URL, MethodTypes.REGISTER, params, this, WSManager.GET_METHOD);
webService.execute();
// BUT I WANT TO RETURN FROM HERE THE CALL FROM THE ACTIVITY....LIKE
return myUser;
}
}
So from the activity this will be:
MyWebServices myService = new MyWebServices();
User usr = myService.getUser(id);
Hope undestand what I tried to describe, thanks!
Upvotes: 0
Views: 1115
Reputation: 22637
learn to love callbacks :)
you cannot apply the pattern you mention (do in background, wait for result, return value) without blocking the UI thread.
the simplest thing is to simply implement the onPostExecute()
method to call the thing you want to do after the REST call completes. you can however get more sophisticated, if you want to expose a clean interface to other parts of the system.
start by reading about the observer pattern. think of it this way: the completion of your REST call is an event, and code that is interested in that event can register to be notified (asynchronously) when it completes. you could do this my making your AsyncTask impl something like this,
AsyncTask myTask = new AsyncTask<...>() {
public interface Callback {
void onComplete();
void onFailure();
}
private Set<Callback> callbacks = new HashSet<Callback>();
public void addObserver(Callback cb) { callbacks.add(cb); }
@Override
protected String doInBackground(Object... params)
{
// whatever
}
@Override
protected void onPostExecute(String result)
{
if (success) {
for (Callback cb: callbacks) {
cb.onComplete();
}
} else {
for (Callback cb: callbacks) {
cb.onFailure();
}
}
}
}
now, the consumer of this interface does something like,
MyTask mt = new MyTask();
mt.addObserver(new MyTask.Callback() {
@Override
public void onComplete() {
// do whatever you want to do when the task completes successfully
}
@Override
public void onFailure() {
// ...
}
}
mt.execute();
Upvotes: 1
Reputation: 43098
What you want leads to blocking UI. Android doesn't allow you to do that. Network calls SHOULD be asynchronous, so the approach is wrong. Deal with response()
method.
UPD: Blocking UI leads to "Application not responsive dialog" which annoys users. Also, what if the network call fails? Or it waits for half an hour to complete?
Upvotes: 1