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

Retrofit 2.0서비스를 이용한 로그인 메소드 호출시, 호출이 여러번 되는것에대해 궁금한점이 있습니다.

0 추천

안녕하세요. 이번에 새로 안드로이드 개발에 참여를 하여 개발을 진행중이다, 레트로핏 2.0을 이용하게되었는데 이해할수없는 증상이 발견되어 이렇게 질문을 드리게되었습니다

현재 저희 어플리케이션에는 다음과 같은 메소드가 있습니다.

Service.getInstance().signIn(email, password);

아래와 같은 내용을 포함하고있습니다

public class Service {
public static final Service INSTANCE = new Service();
private static OkHttpClient.Builder mHttpClient = new OkHttpClient.Builder();
private static ServiceInterface mService;

private static Retrofit mRetrofit;
private Realm mRealm;
private EventBus mEventBus = EventBus.getDefault();
public Service() {
    // 싱글톤 유지
}
public static synchronized Service getInstance() {
    String token = "토큰 공간(비워두겠습니다)";
    mService = createService(ServiceInterface.class, "Token token=" + token);
    return Service.INSTANCE;
}
public static synchronized Service getInstance(final String token) {
    mService = createService(ServiceInterface.class, "Token token=" + token);
    return Service.INSTANCE;
}
-서비스 생성 인스턴트-
private static Gson mGson = new GsonBuilder()
        .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
        .setDateFormat(DATE_FORMAT)
        .setExclusionStrategies(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes f) {
                return f.getDeclaringClass().equals(RealmObject.class);
            }
            @Override
            public boolean shouldSkipClass(Class<?> clazz) {
                return false;
            }
        })
        .create();
-Gson 생성-
public static <S> S createService(Class<S> serviceClass, final String authToken) {
    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);

    mHttpClient.addInterceptor(new Interceptor() {
        @Override
        public okhttp3.Response intercept(Chain chain) throws IOException {
            Request.Builder requestBuilder;
            Request original = chain.request();

            if (authToken != null) {
                requestBuilder = original.newBuilder()
                        .header("Authorization", authToken)
                        .header("Accept", "application/json")
                        .header("Content-Type", "application/json")
                        .method(original.method(), original.body());
            } else {
                requestBuilder = original.newBuilder()
                        .header("Accept", "application/json")
                        .header("Content-Type", "application/json")
                        .method(original.method(), original.body());
            }

            Request request = requestBuilder.build();
            return chain.proceed(request);
        }
    });

    mHttpClient.addInterceptor(logging);
    OkHttpClient client = mHttpClient.build();
    mRetrofit = mBuilder.client(client).build();
    return mRetrofit.create(serviceClass);
}
-레트로핏 서비스 생성-
public void signIn(final String email, final String password) {
    if (StringUtils.isEmpty(email)) {
        return;
    }
    if (StringUtils.isEmpty(password)) {
        return;
    }

    Users users = new Users();
    User user = new User();
    user.setEmail(email);
    user.setPassword(password);
    users.setUser(user);

    Call<Session> call = mService.getSession(users);
    call.enqueue(new Callback<Session>() {
        @Override
        public void onResponse(Call<Session> call, Response<Session> response) {
            if (response.isSuccess()) {

                Session session = response.body();
                Data data = response.body().getData();

                mRealm = Realm.getDefaultInstance();
                
                mRealm.beginTransaction();
                Data realmData = mRealm.createObject(Data.class);
                realmData.setJobId(data.getJobId());
                realmData.setCurrentRole(data.getCurrentRole());
                realmData.setAuthToken(data.getAuthToken());

                Session realmSession = mRealm.createObject(Session.class);
                realmSession.setSuccess(session.getSuccess());
                realmSession.setInfo(session.getInfo());
                realmSession.setData(realmData);
                // When the transaction is committed, all changes a synced to disk.
                mRealm.commitTransaction();
                mRealm.close();

                OnSignInEvent event = new OnSignInEvent();
                event.setSession(response.body());
                event.setResponse(response);
                mEventBus.post(event);
            } else {
                ResponseError error = ErrorUtils.parseError(response);
                OnSignInEvent event = new OnSignInEvent();
                event.setResponseError(error);
                mEventBus.post(event);
            }
        }

        @Override
        public void onFailure(Call<Session> call, Throwable t) {
        }
    });
}
-레트로핏을 이용한 로그인 논리-

 

그이후 다음의 메소드를 호출하는 버튼을 만들어 보았는데

Service.getInstance().signIn(email, password);

그러나 레트로핏의 로그를 체크해본결과 아래와 같은 결과가 나왔는데 이게 버튼을 클릭한 횟수만큼 호출의 수가 기하급수적으로 늘어나는것을 확인할수있었습니다.

--이곳에서 부터 --

 --> POST https://staging.my/api/v1/sessions HTTP/1.1
04-19 D/OkHttp: Content-Type: application/json; charset=UTF-8
04-19 D/OkHttp: Content-Length: 49
04-19 D/OkHttp: Authorization: Token token=
04-19 D/OkHttp: Accept: application/json
04-19 D/OkHttp: {"id":0,"user":{"email":"finjer","password":"f"}}
04-19 D/OkHttp: --> END POST (49-byte body)
-이곳까지 버튼을 누른 수만큼 복사하여 반복적으로 호출이됩니다-

어째서 위와같은 문제가 발생하는지 여쭤봐도 될까요 ...?

개발버전 : 4.3 API 18

Finjer (120 포인트) 님이 2016년 4월 19일 질문

답변 달기

· 글에 소스 코드 보기 좋게 넣는 법
· 질문에 대해 추가적인 질문이나 의견이 있으면 답변이 아니라 댓글로 달아주시기 바랍니다.
표시할 이름 (옵션):
개인정보: 당신의 이메일은 이 알림을 보내는데만 사용됩니다.
스팸 차단 검사:
스팸 검사를 다시 받지 않으려면 로그인하거나 혹은 가입 하세요.
...