2012-03-13 1 views
1

이 작업을 약간 뒤로 할 수는 있지만 아직 적절한 해결책을 찾지 못했음을 알고 있습니다. 먼저 사용자에게 로그인보기를 제공하고 자격 증명의 유효성을 검사하고 로그온에 성공하면 HTTP 200을 반환하는 웹 서비스에 입력 된 자격 증명을 제출합니다. 성공하면 동일한 웹 서비스에 대한 HTTP JSON 요청을 만들어 JSON 객체 목록을 다운로드합니다. 이 객체들은 파싱되어 SQLite DB에 저장됩니다. 약 100 개 이상의 개체가 있으므로 비동기 작업이 매력적이므로 UI를 잠그지 마십시오. 이 점은 ProgressBar (indeterminate)를 사용자에게 표시하여 백그라운드에서 수행중인 작업이 있음을 알린 다음 DB가 채워진 후 별도의 Intent로 반환합니다.비동기 작업 중에 myLooper()가 종료되지 않습니다.

로그인을 검증하고 로그인 조치를 호출 : 다음은 코드 조각입니다

switch(statusCode) { 
    case 200: 
     PrepareLogin doLogin = new PrepareLogin(); 
     doLogin.execute(); 
     if (doLogin.getStatus().equals(AsyncTask.Status.FINISHED)) { 
     // Redirect to intent? 
     } 
     break; 
    case 401: 
     Toast.makeText(Login.this, "Invalid Username/Password", Toast.LENGTH_LONG).show(); 
} 

백그라운드에서 도우미 기능 비동기 작업 :

private class PrepareLogin extends AsyncTask<Void,Void,Void> { 
     ProgressDialog dialog; 
     @Override 
     protected void onPreExecute() { 
      dialog = new ProgressDialog(Login.this); 
      dialog.setTitle(getString(R.string.get_login_dialog_title)); 
      dialog.setMessage(getString(R.string.get_login_dialog_message)); 
      dialog.setIndeterminate(true); 
      dialog.setCancelable(false); 
      dialog.show(); 
     } 
     @Override 
     protected Void doInBackground(Void... params) { 
      Looper.myLooper().prepare(); 
      Looper.myLooper().loop(); 
      DBHelper dbHelp = new DBHelper(Login.this); 
      WSHelper wsHelp = new WSHelper(); 
      long timeNow = System.currentTimeMillis(); 
      dbHelp.resetDB(Login.this); // For dev environment only...remove in prod 
      dbHelp.create(); 
      dbHelp.createUser(username, password, timeNow, "false"); 
      dbHelp.close(); 
      wsHelp.getEmployees(Login.this, username, password); 
      Looper.myLooper().quit(); 
      return null; 
     } 
     protected void onPostExecute() { 
      Intent myIntent = new Intent(login.getContext(), Main.class); 
      startActivityForResult(myIntent, 0); 
      dialog.dismiss(); 
     } 
    } 

유일한 방법 나는 "Handler가 루퍼를 준비해야 함"오류를 던지지 않고이 기능을 사용할 수 있습니다. Looper.myLooper.prepare() 기능이 있습니다.

로그가 연결되고 DB가 채워지지만 대화 상자가 계속 회전하며 비동기 작업의 onPostExecute() 기능에 도달하지 못합니다. 그래도 Looper.myLooper().quit(); 라인을 친다.

모든 주체가 있습니까?

답변

0

"처리기가 ​​루퍼를 준비해야합니다."라는 오류가 발생할 경우 대부분 잘못된 상황에서 AsyncTask를 호출하고있는 것입니다. AsyncTask에서 명시 적으로 Looper.prepare() 함수를 호출해야한다는 것을 기억하지 못합니다. 일단 루퍼를 없애면 괜찮을 것입니다. AsyncTask는 안드로이드에서 가장 사용하기 쉬운 클래스 중 하나입니다. Login 클래스에 코드를 게시해야합니다 (Activity라고 가정합니다).

내가 찾을 수있는 또 다른 문제는 다음과 같습니다

case 200: 
     PrepareLogin doLogin = new PrepareLogin(); 
     doLogin.execute(); 
     if (doLogin.getStatus().equals(AsyncTask.Status.FINISHED)) { 
      // Redirect to intent? 
     } 
break; 

귀하의 doLogin.execute(); 다음 if가 잘못 보장, 그래서 리디렉션 것 결코 화재되도록, 차단 호출해서는 안됩니다.

+0

이것은 실제로 Login 클래스에 있습니다. 사과해야합니다. 내가 믿는 것은 헬퍼 클래스를 호출하여 JSON 데이터를 가져 와서 반복하면서 데이터베이스에 삽입하면 DB의 첫 번째 항목 또는 두 번째 항목에서 중지됩니다. 필자는 헬퍼 클래스를 철저히 테스트하여 데이터베이스가 AsyncTask없이 제대로 채워지는 것을 보았습니다. – Timothy

+0

내 헬퍼 중 하나가 현재 AsyncTask 외부에서 별도의 스레드를 만들고있을 수도 있습니까? 말이 돼? 왜냐하면'Looper.myLooper()'함수를 주석 처리 할 때'Looper.prepare()'를 호출하지 않은 스레드 내부에서 핸들러를 생성 할 수 없으므로 실패합니다. – Timothy

0

내 WSHelper 클래스가 백그라운드 프로세스에서 UI에 일종의 변경을 시도하고있는 것처럼 보입니다. AsyncTask에서 wsHelp 초기화를 제거하고 상수로 만들면 정상적으로 진행될 수있었습니다. wsHelp.getEmployees() 메소드에 대해 반환 값을 void로 변경 한 점도 유의할 필요가 있습니다.