2012-04-17 64 views
0

我试图解决这个问题:我有一个从的AsyncTask扩展一个类,即执行一些HTTP方法是这样的:的AsyncTask没有回调接口

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) 
    { 
    } 

} 

所以,从活动我这样做:

RESTManager webService = new WSManager(URL, MethodTypes.REGISTER, params, this, WSManager.GET_METHOD); 
webService.execute(); 

然后活性接收在callbak方法的响应(因为活动实现该接口):

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

使用Future对象。 – alphazero 2012-04-17 15:05:25

+0

对不起,我的无知是什么,未来的目标是什么? – skabo 2012-04-17 15:14:04

+0

不需要道歉。这是S.O. http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html – alphazero 2012-04-17 15:17:45

回答

1

你想要什么导致阻止用户界面。 Android不允许你这样做。网络调用应该是异步的,所以这种方法是错误的。处理response()方法。

UPD:阻止用户界面导致“应用程序不响应对话框”,这会惹恼用户。另外,如果网络呼叫失败了呢?或者等待半小时才能完成?

+0

是的,我现在说,并同意。但是,处理回复的正确方法是什么?例如用开关(wsMethodExecuted)?因为每个方法都有不同的参数(字符串,用户对象,列表等),所以我将不得不切换methodExecuted并以正确的方式投射参数? – skabo 2012-04-17 14:49:35

1

学会爱回调:)

你不能申请你所提到的模式(做后台,等待结果,返回值),而不会阻塞UI线程。

最简单的事情就是简单地实现onPostExecute()方法来调用你想在REST调用完成之后执行的操作。但是如果您想要将干净的界面展示给系统的其他部分,您可以变得更加复杂。

从阅读关于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(); 
+0

好吧,是的,我喜欢回调!只是有时候我认为代码不清晰或干净,但也许是我的看法。此外,我不确定如何在回调响应方法中实现代码,因为根据我调用的REST方法,结果(参数)会有所不同,请查看我的弗拉基米尔版本,谢谢!编辑:关于参数,onComplete()的参数类型将是一个对象类型?然后根据REST方法调用将其转换为正确的类型? – skabo 2012-04-17 15:02:33

+0

无论具体的呼叫如何,REST呼叫的结果都是相同的。也就是说,它有一个响应代码和一个主体。 'onComplete()'可以将这些参数作为参数,允许调用者检查错误,如果成功,则处理正文结果。 – 2012-04-17 15:12:53

+0

也许我没有表达得很好,在onPostexecute方法中,字符串参数是我从服务接收到的JSON字符串,所以我必须将其解析为我的正确对象(所以在这里我必须知道谁是服务我打电话了解该服务的答案),然后我必须通过onComplete方法传递此对象,probalby传递给服务 – skabo 2012-04-17 15:22:05