Java 无回调接口的异步任务

Java 无回调接口的异步任务,java,android,callback,android-asynctask,Java,Android,Callback,Android Asynctask,我试图解决这个问题:我有一个从AsyncTask扩展而来的类,它执行一些http方法,如下所示: public class RESTManager extends AsyncTask<Object, Object, String> { public RESTManager(String url, MethodTypes myMethod,ICallbackHandler hndl, String restMethod) { initia

我试图解决这个问题:我有一个从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)
    {
    }

}
然后活动在callbak方法中接收响应(因为活动实现了此接口):

这工作正常,但我的问题是,我希望答案出现在对某个函数的相同调用中,然后该函数调用.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);

希望不理解我试图描述的,谢谢

您想要的东西会导致阻塞UI。Android不允许你这么做。网络调用应该是异步的,因此这种方法是错误的。处理
response()
方法

UPD:阻止UI会导致“应用程序无响应对话框”,这会让用户感到烦恼。另外,如果网络呼叫失败怎么办?或者等待半小时才能完成?

学会喜欢回调:)

如果不阻塞UI线程,则无法应用您提到的模式(在后台执行、等待结果、返回值)

最简单的方法是简单地实现
onPostExecute()
方法,在REST调用完成后调用您想要做的事情。但是,如果您想向系统的其他部分公开一个干净的接口,您可以变得更加复杂

从阅读关于这个问题开始。可以这样想:REST调用的完成是一个事件,对该事件感兴趣的代码可以注册为在完成时(异步)收到通知。你可以这样做我让你的AsyncTaskImpl像这样

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();
            }       
        }
    }
}

是的,我现在同意了。但正确的应对方式是什么?例如,使用开关(wsMethodExecuted)?因为每个方法都有不同的参数(字符串、用户对象、列表等),所以我必须切换methodExecuted并以正确的方式转换参数?好的,是的,我喜欢回调!只是有时候我觉得代码不清晰或不干净,但也许是我的感觉。此外,我不知道如何在回调响应方法中实现代码,因为根据我调用的REST方法,结果(参数)会有所不同,请参阅我对Vladimir的回复,谢谢!编辑:与参数相关,onComplete()的参数类型是否为对象类型?然后根据REST方法调用将其强制转换为正确的类型?REST调用的结果是相同的,无论具体调用如何。也就是说,它有一个响应代码和一个主体
onComplete()
可以将这些作为参数,允许调用方检查错误,如果成功,则处理正文结果。可能我没有很好地表达,在onPostexecute方法中,字符串参数是我从服务接收的JSON字符串,因此我必须将其解析为正确的对象(因此,这里我必须知道我调用的服务是谁,以知道该服务的答案)然后我必须通过onComplete方法传递该对象,可能是传递给调用服务的活动。好吧,有两个选项..1)对于每个调用类型都有一个唯一的AsyncTask,对于特定的响应对象类型有一个内部回调。2) 让您的所有“响应”对象从一个公共基扩展,并将其传递给回调方法,或者3)让回调方法只接受一个字符串,并让调用方将其绑定到特定的响应对象类型。对不起,我不知道,什么是未来的对象?无需道歉。这是S.O。
MyWebServices myService = new MyWebServices();
User usr = myService.getUser(id);
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();