2016-06-16 3 views
-2

건물을 개조하면서 데이터를 수집하는 동안 진행률 대화 상자를 보여주는 간단한 재료 디자인 로그인 화면을 만들고 있습니다.UI 스레드를 사용한 2 콜백 문제 업데이트

최근에 2 개로 업그레이드 했으므로 새로운 버전입니다.

LoginActivity에 대한 나의 코드 : LoginActivity에서

private void login(){ 
     Log.d(TAG, "Attempting login"); 

     if(!validate()){ 
      onLoginFailure(); 
      return; 
     } 

     login_button.setEnabled(false); 

     progressDialog = new ProgressDialog(LoginActivity.this, R.style.AppTheme_Dark_Dialog); 
     progressDialog.setIndeterminate(true); 
     progressDialog.setMessage("Authenticating..."); 
     progressDialog.show(); 

     String username = _usernameText.getText().toString().toLowerCase(); //all usernames are lowercase only 
     String password = _passwordText.getText().toString(); 

     //here we handle the NWL section. 

     startTime = System.currentTimeMillis(); 
     NWL.login(username, password, this); //This runs async to UI anyway. 
    } 

그리고 다른 기능 :

@BindView(R.id.login_button) 
Button login_button; 

public void loginOK() { 
     progressDialog.dismiss(); 
     login_button.setEnabled(true); 
     toastCreator.showToastLong("Login OK"); 
     Log.d(TAG, "Total time: " + (System.currentTimeMillis()-startTime)); 
} 

내 NetworkLogic (NWL) 클래스 내 코드 : 이제

public void login(String username, String password, final LoginActivity loginActivity){ 
    LoginUser loginUser = new LoginUser(username, password); 

    Call<Username> call = apiService.login(loginUser); 
    Log.d(TAG, call.toString()); 
    call.enqueue(new Callback<Username>() { 
     @Override 
     public void onResponse(Call<Username> call, Response<Username> response) { 
      Log.d(TAG, "Responsecode : " + response.code()); 
      try { 
       Thread.sleep(2000); //To test if the progressdialog actually shows up 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      if(response.code()==200){ 
       loginActivity.loginOK(); 
      } else { 
       loginActivity.loginFail(); 
      } 
     } 

     @Override 
     public void onFailure(Call<Username> call, Throwable t) { 
      Log.d(TAG, "Failed: " + t.getMessage()); 
      loginActivity.loginFail(); 
     } 
    }); 
} 

내가 계속 다음과 같은 오류가 발생했습니다 : - android.util.AndroidRuntimeException : Animators (loginbutton에 대해서만) 에 대해서만 실행될 수 있습니다. java.lang.RuntimeException : Looper.prepare()를 호출하지 않은 스레드에서 핸들러를 만들 수 없습니다. (toastCreator에 관한)

이 문제는 ui 스레드로 호출을 전달해야 할 때 호출을 수행하는 비동기 스레드 (retrofit 2에서의 비동기 스레드)입니다. 여기 내 질문에이 문제를 해결하는 가장 좋은 해결책은 무엇입니까? 물론 CountdownLatch와 함께 일부 코드를 해킹하고 전체 비동기 호출을 강제 동기화로 실행할 수는 있지만 실제로 찾고있는 것은 아닙니다. 핸들러를 사용해야합니까? 그렇다면 이것을 구현하는 가장 좋은 방법은 무엇입니까?

모든 코드를 사용할 수 있습니다 : https://github.com/mathieudevos/pinkiponki-app

가 답변을 기대하겠습니다!

답변

3

아무도 제대로 질문에 대답하지 않았으므로 여기에 있습니다!

핸들러를 사용하여 메시지를 게시하면 트릭을 수행하는 것 같습니다. 에서 onCreate 방법에서

:

handler = new Handler(Looper.getMainLooper()) { 
     @Override 
     public void handleMessage(Message msg){ 
      switch (msg.what){ 
       case 200: 
        //Got the good response 
        loginOK(); 
        break; 
       case 401: 
        loginFail(); 
        break; 
       default: 
        loginFail(); 
      } 
     } 
    }; 

그리고 내 networklogic 클래스

:

Call<Username> call = apiService.login(userObject); 
    call.enqueue(new Callback<Username>() { 
     @Override 
     public void onResponse(Call<Username> call, Response<Username> response) { 
      Log.d(TAG, "Responsecode: " + response.code()); 
      Message msg = handler.obtainMessage(response.code()); 
      msg.sendToTarget(); 

     } 

     @Override 
     public void onFailure(Call<Username> call, Throwable t) { 
      Log.d(TAG, "Failed: " + t.getMessage()); 
      Message msg = handler.obtainMessage(0); //0 for errors 
      msg.sendToTarget(); 
     } 
} 

이 이후는 mainLooper에서 실행, 나는 이러한 기능의 내 UI와 주변 재생할 수 있습니다. 정답이어야합니다.

0

개조 된 onResponse는 UI 스레드에서 작동하므로 thread.sleep()이 문제를 만듭니다.

Thread.sleep(2000); //This line must not be on UI thread. 

지연이 필요하면 처리기를 쉽게 사용할 수 있습니다.

+0

thread.sleep을 삭제해도 login_button.setEnabled (true)와 관련된 문제가 발생합니다. Error : android.util.AndroidRuntimeException : Animators는 Looper 스레드에서만 실행될 수 있습니다. –

+0

전체 스택 추적을 보내주십시오. – Neo

+0

https://github.com/mathieudevos/pinkiponki-app/blob/master/PinkiPonki/app/src/main/java/com/mattikettu/pinkiponki/LoginActivity.java 오류 코드 (잘못된 암호 제공) : http://pastebin.com/YHcxYy26 –