마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

Asynctask 질문입니다

0 추천

이메일과 비밀번호를 입력하여 로그인 버튼을 눌렀을 시 로그인이 되는 것을 구현중인데

 

쿠키를 만들어 전송하는 부분이 있어 HttpClient를 사용중입니다.

HttpClient를 이용하여 통신을 하려면 쓰레드 이용 처리를 해야한다고 하여 AsyncTask를 이용하고 있는데

 

로그인 버튼을 눌렀을 경우 내부에서 처리를 하여 로그인:1, 비밀번호 오류:2, 기타 오류:0을 리턴하게 해두었습니다.

쿠키를 보내고 응답을 받아 위의 값을 리턴하게 되는데 이 부분이 doInBackground 내에서 처리되도록 하였습니다.

 

그런데 이 부분에서 문제가 되는게 앱을 실행하고 나서 이메일과 비밀번호를 한번 입력한 뒤 로그인을 누르면 쓰레드에서 처리되는 부분이 로그인 버튼을 누른 후 이벤트보다 더 늦게 처리되어 초기값을 리턴하게 됩니다.

바로 로그인 버튼을 누르면 첫 번째 결과에 해당하는 리턴값으로 인식이 되구요

결국 문제가 앱을 실행하고 나서 로그인을 실행할 때 싱크가 맞지 않아 이전 시도에 해당하는 값을 doInBackground에서 리턴한다는 겁니다.

 

추가로 doInBackground와 로그인 결과 관련 메소드 부분 소스 첨부합니다.

 

public void sendCookie() {
	HttpClient client = new DefaultHttpClient();
        HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); 
        HttpResponse response;
        String message = "";
        try {
            HttpPost post = new HttpPost(URL);
            
            CookieStore cookieStore = new BasicCookieStore();
            
            Cookie csrfCookie = new BasicClientCookie(csrfName, csrf);
            cookieStore.addCookie(csrfCookie);
            HttpContext localContext = new BasicHttpContext();
            localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
            
            Log.i("csrf", csrf);
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3);
            nameValuePairs.add(new BasicNameValuePair("zm_sy_prex", csrf));
            nameValuePairs.add(new BasicNameValuePair("email", email));
            nameValuePairs.add(new BasicNameValuePair("password", pswd));
            
            post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            for(int i=0; i<cookie.length; i++)
            	post.addHeader("Cookie",cookie[i].getValue());
            response = client.execute(post);
            String result = "";
            /*Checking response */
            if(response!=null){
                InputStream in = response.getEntity().getContent();
                result = convertInputStreamToString(in);
            }
            else
            	result = "error";
            
            Log.i("seolki", result);
            Pattern pt = Pattern.compile("message\":\"[a-zA-Z ]*");
            Matcher mc = pt.matcher(result);
            if(mc.find()) {
            	message = mc.group(0).substring(10, mc.group(0).length());
            }
            
            Log.i("message", message);
            Log.i("compare",Boolean.toString(message.equals("logged in")));
            if(message.equals("logged in"))
            	logged_in = 1;
            else if(message.equals("incorrect"))
            	logged_in = 2;
            else {
            	logged_in = 0;
            }
            Log.i("logincode", Integer.toString(logged_in));
        } catch(Exception e) {
            e.printStackTrace();
        }
	}	
	
	@Override
	protected Integer doInBackground(Void... params) {
		// TODO Auto-generated method stub
		sendCookie();
		
		return logged_in;
	}

 

seolki (220 포인트) 님이 2014년 8월 18일 질문

1개의 답변

0 추천
doInBackground 메서드 내의 리턴 값인 logged_in은 거기서 사용하는게 아니구요..

onPostExcecute 라는 메서드에서 파라미터로 받아집니다.

결국 순서가 보장되는 내용은 AsyncTask 클래스의 메서드인

doInBackground -> onPostExecute 라는 말이지요..

그러면 doInBackground 에서 return 되는 logged_in 값(완전히 가공된 값)으로 처리하는 부분은

앞서 말씀드린대로 onPostExecute에서 받아서 처리하시면 됩니다.

단순히 AsyncTask 사용법을 모르시는것 뿐인거 같네요.
Gioskhan (12,060 포인트) 님이 2014년 8월 18일 답변
...