我正在尝试解决这个问题:我有一个从AsyncTask扩展的类,它执行一些http方法,如下所示:
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)
{
}
}
所以,从活动I'做到这一点:
RESTManager webService = new WSManager(URL, MethodTypes.REGISTER, params, this, WSManager.GET_METHOD);
webService.execute();
然后活动在callbak方法中接收响应(因为activity实现了这个接口):
public void response(String response)
{
// some process
}
这工作正常,但我的问题是我希望答案来自对某个函数的相同调用,然后该函数调用.execute方法,例如。
// 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;
}
}
所以从活动开始,这将是:
MyWebServices myService = new MyWebServices();
User usr = myService.getUser(id);
希望看不出我试图描述的内容,谢谢!
答案 0 :(得分:1)
您想要的是阻止UI。 Android不允许你这样做。网络调用应该是异步的,因此这种方法是错误的。处理response()
方法。
UPD :阻止用户界面导致&#34;应用程序无响应对话框&#34;这会使用户烦恼。此外,如果网络呼叫失败怎么办?还是等了半个小时才能完成?
答案 1 :(得分:1)
学会爱回调:)
你不能应用你提到的模式(在后台做,等待结果,返回值)而不阻止UI线程。
最简单的方法是在REST调用完成后简单地实现onPostExecute()
方法来调用你想要做的事情。但是,如果你想向系统的其他部分公开一个干净的界面,你可以变得更复杂。
首先阅读observer pattern。以这种方式思考:REST调用的完成是一个事件,对该事件感兴趣的代码可以注册以在完成时通知(异步)。你可以这样做,我的AsyncTask就像这样,
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();
}
}
}
}
现在,这个界面的消费者做了类似的事情,
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();