2012-04-27 160 views
3

我的一個OpenFeint方法來恢復排行榜數據需要一個異步回調到一個方法,該方法應該修改我的一個本地變量(使用一個美妙的黑客)。我現在的問題是,一旦CB被調用,執行繼續,並且由於得分值沒有改變它返回空指針。任何方式來使所有的東西同步或從主函數返回回調值?在Java中處理異步回調

private long getScoreLeaderBoard(String idLeaderBoard) { 
    for (Leaderboard l : OpenFeintX.leaderboards) { 
     if (l.name == null) 
      break; 
     if (l.resourceID().equalsIgnoreCase(idLeaderBoard)) { 
      final Score s[] = new Score[1]; 
      l.getUserScore(OpenFeint.getCurrentUser(), 
        new Leaderboard.GetUserScoreCB() { 

         @Override 
         public void onSuccess(Score score) { 
          s[0] = score; 
         } 
        }); 
      if (s[0] != null) // If user has no score onSuccess get a null 
       return s[0].score; 
      else 
       return 0; 
     } 
    } 

    return 0; 
} 

回調定義:http://m.the9.com/ioshelp/Android_en/doc/com/openfeint/api/resource/Leaderboard.GetUserScoreCB.html

回答

0

覆蓋了的AsyncTask的onPostExecute和你需要在那裏

+0

它沒有一個:(http://m.the9.com/ioshelp/Android_en/doc/com/openfeint/api/resource/Leaderboard.GetUserScoreCB.html – 2012-04-27 14:10:05

+0

的的onSuccess不能返回值對於像getScoreboard這樣的上層方法,這就是爲什麼我使用本地vble.onSuccess需要一些時間來運行,同時執行繼續並返回到返回部分。 – 2012-04-27 14:14:01

0

做的。如果你的方法能忍受而異步回調正在執行阻止什麼,你可以有它創建一個CountDownLatch這樣的:

private long getScoreLeaderBoard(String idLeaderBoard) { 
    final CountDownLatch cdl = new CountDownLatch(1); 
    ... 
        @Override 
        public void onSuccess(Score score) { 
         s[0] = score; 
         cdl.countDown(); 
        } 
    ... 
     cdl.await(); 
     return s[0].score; 
    ... 
} 
+0

這不會阻止我的應用程序一秒嗎?我需要這種方法如果'getScoreLeaderBoard'在UI線程上執行 - 是的,它會一直等到'onSuccess'發生時 – 2012-04-27 14:16:38

+0

最佳:/我會給它一個旋轉,雖然。 – zapl 2012-04-27 14:18:03

+0

這是一個答案,但它可能不會成爲遊戲的一部分 – 2012-04-27 14:22:20

0

,而不是

private long getScoreLeaderBoard(String idLeaderBoard) { /* takes long */ } 

使其

private void requestScoreLeaderBoardUpdate(String idLeaderBoard) { /* takes long */ } 

,並將該處理getScoreLeaderBoard在返回值的代碼(或調用它從方法)onSuccess

這樣你就不必等待並阻止你的線程。

您也可以讓您的活動執行Leaderboard.GetUserScoreCB,然後就像有另一個onCreate, onClick ...類似的方法。

class MyActivity extends Activity implements Leaderboard.GetUserScoreCB { 

    private void requestScoreLeaderBoardUpdate(String idLeaderBoard) { 
     // .. 
     l.getUserScore(OpenFeint.getCurrentUser(), this /* your activity */); 
    } 

    @Override 
    public void onSuccess(Score score) { 
     s[0] = score; 
     // do anything you want with the new score here 
    } 
} 
+0

我試着用你的想法,但你唱第二個方法參數long,這是一個正在改變的參數,但是執行速度仍然太快,我得到了nullPointer。 – 2012-04-27 14:44:58

+0

這不是快速的 - 即使異步線程什麼都不做,只是不能立即得到結果(¹),只能將結果寫入變量。這只是因爲調用'l.getUserScore'的線程繼續執行,直到它返回未變動的變量。 (¹)調度程序可能會停止執行調用線程,並讓另一個在您執行'return'之前執行,但這取決於純運氣。確保你不返回'null'的唯一方法是顯式地停止執行調用線程(這是'cdl.countDown()'的作用) – zapl 2012-04-27 16:21:57

+0

聽起來像你需要重新設計一點,如果這些解決方案不工作。如果你的native/wrapper/handler調用鏈確實需要將分數返回給它,也許你能做的最好的就是使用最近最近緩存的分數,並且希望有一種方法可以通知API有一個更新的分數,一旦你的異步回調執行並且分數改變了。如果沒有,我會尋找其他人如何使用該API的例子,或者尋找一個Feint開發者論壇...... – 2012-04-27 16:48:18