2012-01-11 4 views
0

나는 HTTP 요청 (javax.microedition.io.HttpConnection)을 통해 서버와 통신하는 BlackBerry 응용 프로그램을 개발 중입니다. 장치에서 사용자가 일부 UI 항목을 클릭하면 장치에서 응답을 보내면 UI가 변경되어 서버에서 요청을 보냅니다. UI 스레드가 ProgressDialogScreen을 밀고 팝하는 동안 새로운 스레드에서 통신이 이루어집니다.Blackberry 멀티 스레딩 문제

때때로 응답이오고 ProgressDialogScreen이 팝업되면 UI가 변경되지 않지만 몇 초 후에 UI가 변경됩니다. ProgressDialogScreen이 팝업 될 때와 새로운 Screen이 푸시 될 때 사이에 요청한 경우 엉망이됩니다. 처음으로 가장 오래된 새 화면이 푸시되고 가장 최근의 새 화면이 푸시됩니다. 그리고 이러한 상황은 서버가 잘못된 요청에 응답 한 것처럼 볼 수 있습니다. 이 문제는 시뮬레이터와 장치에서 발생합니다.

다른 문제는 한 요청에 대해 두 가지 동일한 응답을 반환하는 경우가 있습니다. 시뮬레이터에서 로그에서이 두 가지 문제를 볼 수 있었지만 로그를 볼 수 없어서 장치에서이 문제를 볼 수 없었습니다.

편집 :이 코드가 성공적으로 실행

String utf8Response; 
HttpConnection httpConn = null; 
try{ 
    httpConn = (HttpConnection) Connector.open(url); 
    httpConn.setRequestMethod(HttpConnection.GET); 
    httpConn.setRequestProperty("Content-Type", "text/html; charset=UTF8"); 
    if(sessionIdCookie != null){ 
     //may throw IOException, if the connection is in the connected state. 
     httpConn.setRequestProperty("Cookie", sessionIdCookie); 
    } 
}catch (Exception e) { 
    //... 
} 

try{ 
    httpConn.getResponseCode(); 
    return httpConn; 
}catch (IOException e) { 
    // ... 
} 
byte[] responseStr = new byte[(int)httpConn.getLength()]; 
DataInputStream strm = httpConn.openDataInputStream(); 
strm.readFully(responseStr); 
try{ 
    strm.close(); 
}catch (IOException e) { 
    // .... 
} 
utf8Response = new String(responseStr, "UTF-8"); 

경우, 코드 실행 및 새 화면이 조각이 밀려 :

UiApplication.getUiApplication().invokeLater(new Runnable() { 
    public void run() { 
     Vector accounts = Parser.parse(utf8Response,Parser.ACCOUNTS); 
     if (accounts.size() == 0){ 
      DialogBox.inform(Account.NO_DEPOSIT); 
      return; 
     } 
     currentScreen = new AccountListScreen(accounts); 
     changeScreen(null,currentScreen); 
    } 
}); 

public void changeScreen(final AbstractScreen currentScreen,final AbstractScreen nextScreen) { 
    if (currentScreen != null) 
     UiApplication.getUiApplication().popScreen(currentScreen); 
    if (nextScreen != null) 
     UiApplication.getUiApplication().pushScreen(nextScreen); 
} 

EDITv2 :

private static void progress(final Stoppable runThis, String text,boolean cancelable) { 
    progress = new ProgressBar(runThis, text,cancelable); 
    Thread threadToRun = new Thread() { 
     public void run() { 
      UiApplication.getUiApplication().invokeLater(new Runnable() { 
       public void run() { 
        try{ 
         UiApplication.getUiApplication().pushScreen(progress); 
        }catch(Exception e){ 
         Logger.log(e); 
        } 
       } 
      }); 
      try { 
       runThis.run(); 
      } catch (Throwable t) { 
       t.printStackTrace(); 
      } 
      UiApplication.getUiApplication().invokeLater(new Runnable() { 
       public void run() { 
        try { 
         UiApplication.getUiApplication().popScreen(progress); 
        } catch (Exception e) { } 
       } 
      }); 
     } 
    }; 
    threadToRun.start(); 
} 

덧붙여서 ProgressBarnet.rim.device.api.ui.container.PopupScreen에서 확장되고 Stoppable 왜하지 Runnable

+0

실제 코드를 표시하십시오. –

+1

질문 패널에서 위에 사용하고있는 코드를 찾을 수 있습니다. –

+0

팝업 코드가 표시되지 않습니다. 게시 해주세요. 'invokeLater'는 실행될 때마다 괜찮 으면 좋습니다 (예 : 작업의 마지막 일이면 괜찮습니다). 그렇지 않으면'invokeAndWait'을 시도하십시오. –

답변

1

새로운 Screen을 준비하고 푸시 한 후 진행률 표시 줄을 표시하는 것이 좋습니다. 이렇게하면 요청과 응답 사이에 새로운 요청이 없습니다.

0

에서 확장 : 사용자가 UI 스레드에 파싱 같은

private static void progress(final Stoppable runThis, String text,boolean cancelable) { 
    progress = new ProgressBar(runThis, text,cancelable); 
    UiApplication.getUiApplication().pushScreen(progress); 
    [...] 
+0

이것이 어떻게 문제에 대한 좋은 해결책이 될지 이해할 수 없습니다. 조금 설명 할 수 있니? –

0

보인다. ui 스레드에서 Vector accounts = Parser.parse(utf8Response,Parser.ACCOUNTS);을 제거하고 별도의 스레드에서 수행하십시오.

+0

나는 그 질문이 내가 생각한 것만 큼 분명하지 않다고 생각한다. 문제가 가끔 발생하므로 스레딩 직원을 살펴야합니다. –