2012-04-17 78 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