2012-09-19 5 views
0

Activity 중 하나에서 AsyncTask를 사용하여 사용자의 로그인 자격 증명을 다양 화하기 위해 데이터베이스에 연결된 다른 클래스의 메서드를 호출하는 앱이 있습니다. 활동 EntryActivity AsyncTask, carerID, firstName 및 surName의 결과로 업데이트해야하는 세 개의 멤버 변수가 있습니다. 처음 앱을 실행할 때 세 가지 변수 모두 null입니다. 그러나 로그인 버튼을 두 번째로 누르면 변수가 올바르게 설정되고 앱이 정상적으로 작동합니다.Inner AsyncTask 외부 클래스의 멤버 변수를 업데이트하지 않습니다.

앱의 첫 번째 실행에서 세 멤버 변수가 onPostxecute에서 올바르게 설정되지 않은 이유가 있습니까?

.

public class EntryActivity extends NfcBaseActivity{ 

    private LoginWebservice loginWebservice; 
    private static final String TAG = EntryActivity.class.getSimpleName(); 
    private Button login; 
    private EditText userName; 
    private EditText passwordPin; 
    NfcScannerApplication nfcscannerapplication; 
    public static final String CUSTOM_QRCODE_ACTION = "com.carefreegroup.QRCODE_ACTION"; 
    private String carerID; 
    private String firstName; 
    private String surName; 
    private boolean isValidated = false; 


    @Override 
    protected void onCreate(final Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.entryscreen); 
     nfcscannerapplication = (NfcScannerApplication) getApplication(); 
     loginWebservice = new LoginWebservice(this); 
     carerID = null; 
     firstName = null; 
     surName = null; 




     userName = (EditText)findViewById(R.id.username); 
     passwordPin = (EditText)findViewById(R.id.password); 

     login = (Button)findViewById(R.id.buttonlogin); 
     login.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 

       ////////////get user's input/////////// 


       String compId = "100"; 
       String theUsername = userName.getText().toString(); 
       String thePassword = passwordPin.getText().toString(); 
       String loginType = "1"; 



       String[] params = new String[]{compId, theUsername, thePassword, loginType}; 

       //validate user Asynchonously on background thread 
       new AsyncValidateCarer().execute(params); 



       Log.e(TAG, "carerid =" + carerID + " firstname = " + firstName + " surnamee = " + surName); 
       DateTime now = new DateTime(); 
       long loginTime = now.getMillis(); 
       String fullName = firstName +" " + surName; 
       Log.e(TAG, "fullname = " + fullName); 

       if(carerID != null){ 

       ContentValues loginValues = new ContentValues(); 
       loginValues.putNull(LoginValidate.C_ID_INDEX); 
       loginValues.put(LoginValidate.C_CARER_ID, carerID); 
       loginValues.put(LoginValidate.C_COMP_ID, compId); 
       loginValues.put(LoginValidate.C_CARER_NAME, fullName); 
       loginValues.put(LoginValidate.C_PASSWORD, thePassword); 
       loginValues.put(LoginValidate.C_DATE_TIME, loginTime); 
       nfcscannerapplication.loginValidate.insertIntoCarer(loginValues); 

       Toast.makeText(
         EntryActivity.this, 
         "Carer logged in to System", 
         Toast.LENGTH_LONG).show(); 

       isValidated = true; 

       Intent intent = new Intent(EntryActivity.this, 
         NfcscannerActivity.class); 
       intent.setAction(CUSTOM_QRCODE_ACTION); 
       startActivity(intent); 


       }else{ 

        Toast.makeText(
          EntryActivity.this, 
          "Please check credentials", 
          Toast.LENGTH_LONG).show(); 

       } 
       //////////////validate user///////////////// 





      } 
     }); 

     Button changeUser = (Button)findViewById(R.id.buttonchangeuser); 
     changeUser.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       Log.e(TAG, "change user button clicked"); 
       nfcscannerapplication.loginValidate.deleteTableCarer(); 
       Toast.makeText(
         EntryActivity.this, 
         "Carer logged out", 
         Toast.LENGTH_LONG).show(); 
       EntryActivity.this.onCreate(savedInstanceState); 
      } 
     }); 


    }//end of onCreate 

    private void hideSoftKeyboard() { 

     InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
     imm.hideSoftInputFromWindow(passwordPin.getWindowToken(), 0); 

    } 

    private class AsyncValidateCarer extends AsyncTask<String, Void, ContentValues> { 

     @Override 
     protected ContentValues doInBackground(String... params) { 

      ContentValues cv = null; 

      try { 
       Log.e(TAG, "inside asynctask"); 
       cv = loginWebservice.validateCarer(params[0], params[1], params[2], params[3]); 
       if (cv != null){ 
        Log.e(TAG, "cv = not null!"); 
       } 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      return cv; 

     } 

     @Override 
     protected void onPostExecute(ContentValues result) { 
      Log.e(TAG, "inside onpostexecute"); 

      EntryActivity.this.carerID = (String) result.get("carerID"); 
      EntryActivity.this.firstName = (String) result.get("firstname"); 
      EntryActivity.this.surName = (String) result.get("surname"); 
     } 
    } 

} 

[업데이트]

private class AsyncValidateCarer extends AsyncTask<String, Void, Void> { 

     @Override 
     protected Void doInBackground(String... params) { 

      ContentValues cv = null; 

      try { 
       Log.e(TAG, "inside doInBackground"); 
       cv = loginWebservice.validateCarer(params[0], params[1], params[2], params[3]); 
       carerID = (String) cv.get("carerID"); 
       firstName = (String) cv.get("firstname"); 
       surName = (String) cv.get("surname"); 
       if (cv != null){ 
        Log.e(TAG, "cv = not null! and exiting doInBackground"); 
       } 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      return null; 


     } 


    } 

답변

1

A syncTask는 비동기 적으로 실행되므로 "execute"메서드 호출 후에 작업이 실제로 완료된다는 보장이 없습니다. 내 충고는 "onPostExecute"메소드에서 "실행"호출 이후의 모든 항목 (또는 적어도 해당 필드와 관련된 항목)을 이동하는 것입니다.

첫 번째 클릭이 작동하지 않는 이유는 두 번째 작동이 첫 번째 '로그인'클릭과 두 번째 사이에서 완료되기 때문에 AsyncTask가 완료 될 때까지 기다리는 것입니다. 따라서 두 번째 클릭하면 첫 번째 실행 결과가 표시됩니다. 무슨 일이 일어나고 있는지 이해하려면 "로그"메시지를 "onPostExecute"에 추가하십시오.

희망 하시겠습니까?

+0

.execute() 호출 후에 Thread.sleep (3000)을 배치하여 어제이 지점을 실제로 테스트했습니다. – turtleboy

+0

아니, 단지 5000의 지연으로 시도했지만, 세 변수 모두 여전히 null이다. – turtleboy

+0

나는 3 개의 값을 onPostExecute()에 로그 아웃했고 모두 설정되었다. 왜 그들은 첫 번째 실행시에 메소드 밖으로 설정되지 않습니까? – turtleboy

0
carerID = null; 
firstName = null; 
surName = null; 

제거가 문 onCreate() 방법에서, 위의 그들은이 Class Scope에로 기본값으로 초기화 되었습니다로 및 은 (는) Instance Variables.

+0

아무런 차이가 없습니다. carerID는 처음 실행시 null입니다. – turtleboy

+0

@turtleboy 다른 2 명의 firstName과 surName은 어떨까요? 그리고 pls는 carerID를 null로 어딘가에 초기화하는지 확인합니다. 다른 2가 온다면 원인도 역시 나타납니다. –

+0

3 명이 모두옵니다. 다시 널. 3 번 모두 로그인 버튼을 다시 누르면 설정됩니다. – turtleboy

관련 문제