- 로그인 기능 구현하기 - 로그인하고 sharedpreference를 이용해서 자기 정보 다시 조회하는 기능
- Retrofit 비동기식으로 작동됨에 따른 실행 순서 문제
오늘은 학원 알바가 있는 날이기도 하고 목요일은 원래 쉬엄쉬엄 하는 날이라 개발을 안해야지 하다가 그래도 조금이라도 해보려고 이렇게 글을 쓴다.
그래도 특정 부분에서 막히지 않으니까 요즘은 개발에 대한 의욕과 욕심이 생기는 것 같아서 기분이 좋다.
그러나 개발일지랑 공부한 부분 정리는 조금 소홀해진 경향이 있는 듯 하다😥
Retrofit 구현하는데 나름 힘들게 찾아내건데 그거 정리해야지 조만간.. 정리 안하면 또 까먹는다구
HTTP 통신을 통해서 데이터를 받는 방식에는 동기식과 비동기식 두 가지의 방식이 있다.
동기(synchronous: 동시에 일어나는) : 동기는 말 그대로 동시에 일어난다는 뜻이다. 요청과 요청에 따른 결과가 동시에 일어나기 때문에 요청을 하면 시간이 얼마나 걸리든지 상관없이 요청의 결과가 무사히 나올때 까지 다음 단계로 넘어가지 않고 기다린다. 따라서 특정 노드의 요청에 따른 결과가 아직 나오지 않았으면 다른 노드들은 실행되지 않는다.
비동기(Asynchronous: 동시에 일어나지 않는): 비동기는 동시에 일어나지 않는다를 의미한다. 요청과 결과가 동시에 일어나지 않기 때문에 요청한 그 자리에서 결과가 주어지지 않고 따라서 노드 사이의 작업 처리 단위를 동시에 맞추지 않기 때문에 특정 노드에서 요청한 결과가 아직 안왔더라도 다른 노드가 실행된다.
보다 빠른 이해와 비동기식, 동기식 통신 개념의 중요성을 와닿게 하기 위해서 내가 겪었던 상황을 구체적으로 정리해두려고 한다.
@Override
public void onClick(View view) {
switch(view.getId()){
case R.id.btn_login:
//사용자 입력 id,pw 가져오기
String id = et_id2.getText().toString();
String pw = et_pass2.getText().toString();
// memberAPI 연결 활성화하기
MemberAPI memberAPI = RetrofitClient.getInstance().create(MemberAPI.class);
Call<LoginResponseInfo> loginResponseInfoCall = memberAPI.login(id,pw);
loginResponseInfoCall.enqueue(new Callback<LoginResponseInfo>() {
@Override
public void onResponse(Call<LoginResponseInfo> call, Response<LoginResponseInfo> response) {
if(response.isSuccessful()){
Log.d("HTTP","로그인 성공");
LoginResponseInfo responseInfo = response.body();
//Editor를 preferences에 쓰겠다고 연결
SharedPreferences.Editor editor = preferences.edit();
//putString(Key,Value)
String userId = responseInfo.getMemberId();
String nickname = responseInfo.getNickname();
editor.putString("userId", responseInfo.getMemberId());
editor.putString("nickname",responseInfo.getNickname());
//항상 commit & apply를 해야 저장
editor.commit();
}
else{Log.d("HTTP","로그인 실패");}
}
@Override
public void onFailure(Call<LoginResponseInfo> call, Throwable t) {
Log.d("HTTP","로그인 연결 실패 ");
Log.e("연결실패", t.getMessage());
}
});
break;
...
//Main.Activity로 넘어가기
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
finish();
내가 구현하고자 했던 내용 시나리오
1. login activity 에서 login 버튼이 클릭되면 edittextview에서 각각 사용자 입력 id와 password를 받아와서 id와 pw 변수에 저장한다.
2. login 회원 정보를 조회하는 API를 불러와서 해당 id와 pw값을 넣어 id와 pw가 일치하는 사용자의 loginresponseinfo(아이디, 닉네임, PK)를 받아온다.
3. 받아온 loginresponseinfo에 해당하는 3개의 변수 데이터를 각각 sharedPreferences에 넣는다.
4. Main Activity로 화면을 전환시킨 후 sharedPreferences 에서 3에서 넣은 데이터들을 꺼내 회원 정보를 출력해준다.
그러나 실행을 시켜보면 디버깅 했을때 MainActivity로 먼저 넘어가서 예전 sharedpreference 데이터가 먼저 출력되고 그 이후에 로그인한 정보가 sharedpreference에 뒤늦게 저장되었다
이렇게 순서가 진행된 이유는 HTTP 통신으로 로그인 데이터를 보내고 회원 데이터를 받아오는데 시간이 걸리는데 Retrofit이 비동기식이라 그 요청을 기다리지 않고 바로 다음 메소드가 실행되기 때문이였다.
따라서 이를 해결하기 위해서는 retrofit이 실행되는 메소드 안에 요청 코드 이후에 실행할 코드를 작성해야 한다