Android

<Android> 로그인 기능 구현 (2)

DDunTory 2020. 7. 28. 14:00

api 서버 연동할 때는 UI 멈춤현상이 없어야 하므로, UI Thread가 아닌 Background Thread에서 비동기 연동을 합니다.

 

onCreate메소드 안에서 로그인 버튼을 눌렀을 때, 비동기 연동이 실행 되어야 하는데요! 코드로 살펴보겠습니다.

 

/* onCreate 메소드 내에서 로그인버튼 findviewbyid를 한 후, 버튼 클릭 리스너 시 */
login_button.setOnClickListener(new View.OnClickListener() {//로그인 버튼 클릭

            @Override
            public void onClick(View v) {
                login_request lr = new login_request();
                lr.execute();// 비동기 연동 시작
            }
        });

login_request는 AsyncTask 클래스 이름이고, 로그인 버튼을 누를 때, 비동기 연동이 시작되게 코드를 짰습니다.

 

다음으로는 AsyncTask를 보겠습니다.

public class login_request extends AsyncTask<Void, Void, String> {

        @Override
        public String doInBackground(Void... strings) {
            try {
                String value;
                String params = "email=" + email_edittext.getText().toString() + "&password=" + password_edittext.getText().toString();//파라미터

                URL url = new URL("api서버 url");//url 지정

                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");//보내는 방식
                conn.setRequestProperty("Accept", "application/json");//받는방식 json
                conn.setRequestMethod("POST");//요청방식 : POST

                conn.setDoInput(true);//InputStream으로 서버로부터 응답받겠다는 옵션
                conn.setDoOutput(true);//OutputStream으로 POST 데이터 넘겨주겠다는 옵션

                OutputStream outs = conn.getOutputStream();
                OutputStreamWriter outs_w = new OutputStreamWriter(outs, StandardCharsets.UTF_8);//받아오는거 utf-8 인코딩
                outs_w.write(params);//params를 POST 형식으로 데이터 넘겨줌
                outs_w.flush();//버퍼에 데이터 모두 출력시키고 비움
                outs_w.close();//자원풀기
                outs.close();//풀기

                InputStream is = null;
                BufferedReader in = null;
                String data = "";

                is = conn.getInputStream();
                in = new BufferedReader(new InputStreamReader(is));
                String line = null;
                StringBuffer buff = new StringBuffer();

                while ((line = in.readLine()) != null) {//버퍼로 데이터 읽기
                    buff.append(line + "\n");
                }

                data = buff.toString().trim();//data에 json형식을 읽은 데이터 대입.

                JSONObject json_response = new JSONObject(data);//json객체에 연결
                Boolean result = Boolean.parseBoolean(String.valueOf(json_response.get("result")));//data에 있는 string 형태의 result 값을 boolean으로 parse 함 

                if (result) {//DB에 데이터랑 params의 데이터가 일치할 시 액티비티 전환
                    value = String.valueOf(json_response.get("받을 데이터의 key값"));
                    shared_preferences_email.set_user_email(login_activity.this, user_email);//앱 로컬에 데이터 저장을 하기위해 sharedpreferences 사용

                    Intent intent = new Intent(login_activity.this, 다음 액티비티.class);
                    startActivity(intent);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);//자동 로그인 이므로 이전 액티비티 스택제거
                } else {
                    Log.e("Login", "FAILED");
                }
            } catch (MalformedURLException | ProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }

            return null;
        }
    }

서버로 넘기는 파라미터는 email과 password 이고 데이터베이스에 매칭 값이 존재하면, Json 객체 형식으로 "result" 및 여러 데이터를 key value로 받게됩니다.

 

이를 JsonObject로 연결시켜, result 값을 boolean 형태로 반환시킨 후에 if문을 걸어줍니다.

 

true 일때는 다음 액티비티로 intent하고 자동 로그인으로 구상을 짤 생각이어서 이전 액티비티 스택을 제거합니다.

 

이렇게 비동기 연동에 대해 알아보았습니다!

 

*번외*

AsyncTask는 사용법도 복잡하고, 필요 시 각 액티비티 클래스마다 호출 시켜야 하며, 글로벌하게 사용할 수 없습니다. HTTP 통신에 특화 되어있고, 어노테이션방식으로 더 명확하게 사용할 수 있으며, AsyncTask에 비해 속도에서 3배가량 우위에있는 Retrofit2에 대해 학습 후 포스팅 하겠습니다.