2012-04-27 4 views
3

리더 보드 데이터를 복구하는 OpenFeint 메소드 중 하나는 멋진 해킹을 사용하여 내 로컬 변수 중 하나를 수정해야하는 메소드에 대한 비동기 콜백이 필요합니다. 내 문제는 이제 CB가 호출되면 실행이 계속되고 스코어 값이 변경되지 않았으므로 nullPointer를 반환합니다. 모든 것을 동기화하거나 메인 함수에서 콜백 값을 반환하는 방법은 없나요?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 –

+0

는 onSuccess는 값을 반환 할 수 없습니다 getScoreboard와 같은 상위 메소드의 경우 로컬 vble을 사용하는 이유입니다. onSuccess는 실행하는 데 약간의 시간이 걸리는 반면 실행은 계속되고 리턴 파트로갑니다. –

0

에서해야 할 일을, 당신은 할 수

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

이 응용 프로그램이 1 초 동안 중지되지 않습니까? UI 스레드에서'getScoreLeaderBoard'가 실행되면 –

+0

은'onSuccess'가 발생할 때까지 기다린다. – zapl

+0

대답이지만, 아마도 그렇지 않을 것이다. 최적의 :/나는 그것에게 회전을 줄 것이다. –

0

대신:이 같은 CountDownLatch을 만들 수 있습니다

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

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

하고있는 getScoreLeaderBoard의 ReturnValue를 처리하는 코드를 넣어 (또는 그것에서의 메소드 호출)을 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를 얻습니다. –

+0

빨리 처리하지 않아도됩니다. 비동기 스레드가 아무것도하지 않고 결과를 변수에 쓰더라도 결과를 즉시 얻을 수는 없습니다. 이는'l.getUserScore'를 호출하는 스레드가 변경되지 않은 변수를 반환 할 때까지 계속 실행되기 때문입니다. (¹) 스케줄러가 호출 스레드의 실행을 멈추고'return'을 치기 전에 다른 스레드를 실행하게 할 수 있습니다. 그러나 그것은 순수한 운에 달려 있습니다. 당신이'null'을 반환하지 않는다는 것을 확신 할 수있는 유일한 방법은 명시 적으로 실행중인 호출 스레드를 멈추는 것입니다 ('cdl.countDown()'이 무엇입니까?) – zapl

+0

당신이 비트를 재 설계 할 필요가있는 것처럼 들립니다. 일하지 마. 네이티브/래퍼/핸들러 호출 체인에서 실제로 점수를 반환해야하는 경우 가장 최근에 캐시 된 점수를 사용하는 것이 가장 좋으며 API에 업데이트 된 점수가 있음을 알리는 방법이 있습니다. 일단 비동기 콜백이 실행되고 점수가 변경되면 그렇지 않다면 다른 사람들이 API를 사용하는 방법에 대한 예를 살펴 보거나 Feint 개발자 포럼을 찾아 보겠습니다. –