Logowanie za pomocą Retrofit 2

308

Usiłuję uzyskać dokładnie JSON, który jest wysyłany w żądaniu. Oto mój kod:

OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor(){
   @Override public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
      Request request = chain.request();
      Log.e(String.format("\nrequest:\n%s\nheaders:\n%s",
                          request.body().toString(), request.headers()));
      com.squareup.okhttp.Response response = chain.proceed(request);
      return response;
   }
});
Retrofit retrofit = new Retrofit.Builder()
   .baseUrl(API_URL)
   .addConverterFactory(GsonConverterFactory.create())
   .client(client).build();

Ale widzę to tylko w dziennikach:

request:
com.squareup.okhttp.RequestBody$1@3ff4074d
headers:
Content-Type: application/vnd.ll.event.list+json

Jak mam wykonać prawidłowe logowanie, biorąc pod uwagę usunięcie setLog()i setLogLevel()którego używaliśmy z Retrofit 1?

Gabor
źródło

Odpowiedzi:

697

W Retrofit 2 powinieneś użyć HttpLoggingInterceptor .

Dodaj zależność do build.gradle. Najnowsza wersja z października 2019 roku to:

implementation 'com.squareup.okhttp3:logging-interceptor:4.2.1'

Utwórz Retrofitobiekt podobny do następującego:

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://backend.example.com")
        .client(client)
        .addConverterFactory(GsonConverterFactory.create())
        .build();

return retrofit.create(ApiClient.class);

W przypadku ostrzeżeń o rezygnacji po prostu zmień setLevelna:

interceptor.level(HttpLoggingInterceptor.Level.BODY);

Powyższe rozwiązanie daje ci komunikaty logcat bardzo podobne do starych ustawionych przez

setLogLevel(RestAdapter.LogLevel.FULL)

W przypadkujava.lang.ClassNotFoundException :

Starsza wersja modernizacji może wymagać starszej logging-interceptorwersji. Szczegółowe informacje można znaleźć w sekcjach komentarzy.

klimat
źródło
30
Zostało to dodane do OkHttp zaledwie 15 dni po moim pytaniu, fajnie, że potrzeby społeczności mają tak szybki wpływ!
Gabor
1
i nie musisz już dodawać repozytorium migawek sonatype do swojego build.gradle
James Goodwin
13
retrofit 2.1.0 użyj tej kompilacji 'com.squareup.okhttp3: Logowanie-przechwytywacz: 3.3.1'
jayellos
2
@jayellos Dzięki za oznaczenie tego. Jeśli używasz wersji niższej niż 3.3.1, nie otrzymasz takiego wyjątku od metody.
guydemossyrock
2
Dostaję: nie znalazłeś żadnego pomysłu na „okhttp3.internal.Platform”?
corlaez,
35

Spotkałem się z Tobą i próbowałem zapytać autora książki Retrofit: Uwielbiam pracować z interfejsami API na Androidzie (tutaj jest link ) (nie! Nie robię dla nich reklam ... ale są naprawdę fajne chłopaki :) A autor odpowiedział mi bardzo szybko, zarówno metodą Log na Retrofit 1.9, jak i Retrofit 2.0-beta.

A oto kod Retrofit 2.0-beta:

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();  
// set your desired log level
logging.setLevel(Level.BODY);

OkHttpClient httpClient = new OkHttpClient();  
// add your other interceptors …

// add logging as last interceptor
httpClient.interceptors().add(logging);  // <-- this is the important line!

Retrofit retrofit = new Retrofit.Builder()  
   .baseUrl(API_BASE_URL)
   .addConverterFactory(GsonConverterFactory.create())
   .client(httpClient)
   .build();

Oto jak dodać metodę rejestrowania za pomocą HttpLoggingInterceptor . Również jeśli jesteś czytelnikiem tej książki, o której wspomniałem powyżej, może się okazać, że mówi ona, że ​​nie ma już metody logowania w Retrofit 2.0 - co, jak poprosiłem autora, jest nieprawidłowe i będą aktualizować książkę w przyszłym roku, mówiąc o tym.

// Jeśli nie jesteś zaznajomiony z metodą Log w Retrofit, chciałbym podzielić się czymś więcej.

Należy również zauważyć, że istnieje kilka poziomów rejestrowania, które można wybrać. Używam Level.BODY przez większość czasu, co da coś takiego:

wprowadź opis zdjęcia tutaj

Na obrazie można znaleźć prawie cały personel http: nagłówek, treść i odpowiedź itp.

A czasami naprawdę nie potrzebujesz wszystkich gości, aby wziąć udział w przyjęciu: chcę tylko wiedzieć, czy połączenie jest udane, że połączenie internetowe zostało pomyślnie wykonane w ramach mojego Activiy & Fragmetn. Wtedy możesz swobodnie korzystać z Level.BASIC , który zwróci coś takiego:

wprowadź opis zdjęcia tutaj

Czy możesz znaleźć kod stanu 200 OK w środku? To jest to :)

Jest też inny, Level.HEADERS , który zwróci tylko nagłówek sieci. Masz oczywiście kolejne zdjęcie:

wprowadź opis zdjęcia tutaj

To wszystko z logowania;)

I chciałbym podzielić się z tutorialem, którego wiele się tam nauczyłem . Mają świetny post mówiący o prawie wszystkim związanym z Retrofit i kontynuują aktualizację postu, w tym samym czasie nadchodzi Retrofit 2.0. Proszę spojrzeć na te prace, które moim zdaniem pozwolą ci zaoszczędzić dużo czasu.

Anthonyeef
źródło
Skąd pochodzi HttpLoggingInterceptor?
Radu,
5
To też nie działa dla mnie. httpClient.interceptors.add chce com.squareup.okhttp.Interceptor, a nie okhttp3.logging.HttpLoggingInterceptor
Radu
@Radu Na której wersji modernizacji korzystasz? Twoja klasa powinna mieć coś takiego: skompiluj 'com.squareup.retrofit2: retrofit: 2.0.0-beta4'
peitek
Nie działałoby to w przypadku rejestrowania nagłówków żądań, ponieważ konieczne jest dodanie Interceptora, takiego jak interceptor sieciowy! Zobacz: stackoverflow.com/a/36847027/2557258
Yazon2006 25.04.16
12

Oto Interceptordziennik, który rejestruje zarówno treść żądania, jak i odpowiedź (za pomocą Timber, na podstawie przykładu z dokumentów OkHttp i niektórych innych odpowiedzi SO):

public class TimberLoggingInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        long t1 = System.nanoTime();
        Timber.i("Sending request %s on %s%n%s", request.url(), chain.connection(), request.headers());
        Timber.v("REQUEST BODY BEGIN\n%s\nREQUEST BODY END", bodyToString(request));

        Response response = chain.proceed(request);

        ResponseBody responseBody = response.body();
        String responseBodyString = response.body().string();

        // now we have extracted the response body but in the process
        // we have consumed the original reponse and can't read it again
        // so we need to build a new one to return from this method

        Response newResponse = response.newBuilder().body(ResponseBody.create(responseBody.contentType(), responseBodyString.getBytes())).build();

        long t2 = System.nanoTime();
        Timber.i("Received response for %s in %.1fms%n%s", response.request().url(), (t2 - t1) / 1e6d, response.headers());
        Timber.v("RESPONSE BODY BEGIN:\n%s\nRESPONSE BODY END", responseBodyString);

        return newResponse;
    }

    private static String bodyToString(final Request request){

        try {
            final Request copy = request.newBuilder().build();
            final Buffer buffer = new Buffer();
            copy.body().writeTo(buffer);
            return buffer.readUtf8();
        } catch (final IOException e) {
            return "did not work";
        }
    }
}
david.mihola
źródło
6

Spróbuj tego:

Request request = chain.request();
Buffer buffer = new Buffer();
request.body().writeTo(buffer);
String body = buffer.readUtf8();

Następnie w bodyJSON jesteś zainteresowany.

Anton Ryabyh
źródło
1
jak wydrukować odpowiedź organizmu?
Gilberto Ibarra,
3
@ Wykorzystanie GilbertoIbarra String bodyString = response.body().string(); log(bodyString); response = response.newBuilder().body(ResponseBody.create(response.body().contentType(), bodyString)).build(); (Nie możesz odczytać treści odpowiedzi więcej niż raz, więc będziesz musiał utworzyć nową odpowiedź z konstruktorem)
Anton Ryabyh
To kula, której nie potrzebujemy więcej. Oto przykład działającego rejestrowania: stackoverflow.com/a/36847027/2557258
Yazon2006 25.04.16
6

Głównym problemem, z jakim się spotkałem, było dynamiczne dodawanie nagłówków i logowanie ich do debugowania logcat. Próbowałem dodać dwa przechwytywacze. Jeden do logowania i jeden do dodawania nagłówków w drodze (autoryzacja tokena). Problem polegał na tym, że możemy .addInterceptor lub .addNetworkInterceptor. Jak powiedział mi Jake Wharton: „Przechwytywacze sieciowe zawsze pojawiają się po przechwytywaczach aplikacji. Zobacz https://github.com/square/okhttp/wiki/Interceptors ”. Oto przykład działania z nagłówkami i dziennikami:

OkHttpClient httpClient = new OkHttpClient.Builder()
            //here we can add Interceptor for dynamical adding headers
            .addNetworkInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request request = chain.request().newBuilder().addHeader("test", "test").build();
                    return chain.proceed(request);
                }
            })
            //here we adding Interceptor for full level logging
            .addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
            .build();

    Retrofit retrofit = new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create(gsonBuilder.create()))
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .client(httpClient)
            .baseUrl(AppConstants.SERVER_ADDRESS)
            .build();
Yazon2006
źródło
5

Nie wiem, czy setLogLevel () powróci w końcowej wersji Retrofit 2.0, ale na razie możesz użyć przechwytywacza do logowania.

Dobry przykład można znaleźć na wiki OkHttp: https://github.com/square/okhttp/wiki/Interceptors

OkHttpClient client = new OkHttpClient();
client.interceptors().add(new LoggingInterceptor());

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://www.yourjsonapi.com")
        .addConverterFactory(GsonConverterFactory.create())
        .client(client)
        .build();
oceanfeeling
źródło
albo nie przeczytałeś mojego pytania, albo nie przeczytałeś strony, do której prowadzisz ... ponieważ LoggingInterceptor nie próbuje zalogować treści żądania (a więc nie rozwiązuje mojego problemu)
Gabor
Dostaję „UnsupportedOperationException”
Choletski
5

Jeśli używasz Retrofit2 i okhttp3, musisz wiedzieć, że Interceptor działa w kolejce. Dodaj na końcu interfejs APIInterceptor, po pozostałych Interceptorach:

HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        if (BuildConfig.DEBUG)
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);

 new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .addInterceptor(new CatalogInterceptor(context))//first
                .addInterceptor(new OAuthInterceptor(context))//second
                .authenticator(new BearerTokenAuthenticator(context))
                .addInterceptor(loggingInterceptor)//third, log at the end
                .build();
NickUnuchek
źródło
4

Dla tych, którzy potrzebują logowania wysokiego poziomu przy modernizacji, użyj przechwytywacza w ten sposób

public static class LoggingInterceptor implements Interceptor {
    @Override public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        long t1 = System.nanoTime();
        String requestLog = String.format("Sending request %s on %s%n%s",
                request.url(), chain.connection(), request.headers());
        //YLog.d(String.format("Sending request %s on %s%n%s",
        //        request.url(), chain.connection(), request.headers()));
        if(request.method().compareToIgnoreCase("post")==0){
            requestLog ="\n"+requestLog+"\n"+bodyToString(request);
        }
        Log.d("TAG","request"+"\n"+requestLog);

        Response response = chain.proceed(request);
        long t2 = System.nanoTime();

        String responseLog = String.format("Received response for %s in %.1fms%n%s",
                response.request().url(), (t2 - t1) / 1e6d, response.headers());

        String bodyString = response.body().string();

        Log.d("TAG","response"+"\n"+responseLog+"\n"+bodyString);

        return response.newBuilder()
                .body(ResponseBody.create(response.body().contentType(), bodyString))
                .build();
        //return response;
    }
}

public static String bodyToString(final Request request) {
    try {
        final Request copy = request.newBuilder().build();
        final Buffer buffer = new Buffer();
        copy.body().writeTo(buffer);
        return buffer.readUtf8();
    } catch (final IOException e) {
        return "did not work";
    }
}`

Dzięki uprzejmości : https://github.com/square/retrofit/issues/1072#

DGN
źródło
powinieneś wspomnieć, że skopiowałeś z github.com/square/retrofit/issues/1072# (aby podziękować swojemu źródłu)
Gabor
To kula, której nie potrzebujemy więcej. Oto przykład działającego rejestrowania: stackoverflow.com/a/36847027/2557258
Yazon2006 25.04.16
4

Kod Kotlin

        val interceptor = HttpLoggingInterceptor()
        interceptor.level = HttpLoggingInterceptor.Level.BODY
        val client = OkHttpClient.Builder().addInterceptor(interceptor).build()
        val retrofit = Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build()

        return retrofit.create(PointApi::class.java)
Jorge Casariego
źródło
2

Możesz także dodać Stetho z Facebooka i przeglądać ślady sieciowe w Chrome: http://facebook.github.io/stetho/

final OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {
    builder.networkInterceptors().add(new StethoInterceptor());
}

Następnie otwórz „chrome: // inspect” w Chrome ...

kenyee
źródło
2

Spowoduje to utworzenie obiektu modernizującego za pomocą funkcji Logging. bez tworzenia osobnych obiektów.

 private static final Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(new OkHttpClient().newBuilder()
                    .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
                    .readTimeout(READ_TIMEOUT_SECONDS, TimeUnit.SECONDS)
                    .writeTimeout(WRITE_TIMEOUT_SECONDS, TimeUnit.SECONDS)
                    .connectTimeout(CONNECTION_TIMEOUT_SECONDS, TimeUnit.SECONDS)
                    .build())
            .addConverterFactory(GsonConverterFactory.create())
            .build();
Jay Dangar
źródło
2

Najpierw dodaj zależność do build.gradle:

implementacja „com.squareup.okhttp3: logowanie-przechwytywacz: 3.12.1”

Podczas korzystania z Kotlin możesz dodać Logging Interceptor w następujący sposób:

companion object {
    val okHttpClient = OkHttpClient().newBuilder()
            .addInterceptor(HttpLoggingInterceptor().apply {
                level = HttpLoggingInterceptor.Level.BODY
            })
            .build()


    fun getRetrofitInstance(): Retrofit {
        val retrofit = Retrofit.Builder()
                .client(okHttpClient)
                .baseUrl(ScanNShopConstants.BASE_URL)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build()

        return retrofit
    }
}
Vinay John
źródło
2

Poniższy zestaw kodu działa dla mnie bez żadnych problemów

Gradle

// Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.12.1'

RetrofitClient

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);

OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(logging)
        .build();

retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .client(client)
        .build();

Można również zweryfikować wyniki, przechodząc do zakładki Profiler na dole Android Studio, a następnie klikając + znak, aby rozpocząć nową sesję, a następnie wybierz żądany skok w „Sieci”. Tam możesz zdobyć wszystko, ale jest to uciążliwe i powolne. Zobacz zdjęcie poniżej.

wprowadź opis zdjęcia tutaj

Smoczy ogień
źródło
1

Najlepszym sposobem na zrobienie tego dobrze w Retrofit 2 jest dodanie przechwytywacza rejestratora jako sieci. Interceptor wydrukuje nagłówki sieciowe i nagłówki niestandardowe. Ważne jest, aby pamiętać, że przechwytywacz działa jako stos i pamiętaj, aby na końcu dodać program rejestrujący.

OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(new MyCustomInterceptor());
builder.connectTimeout(60, TimeUnit.SECONDS);
builder.readTimeout(60, TimeUnit.SECONDS);
builder.writeTimeout(60, TimeUnit.SECONDS);
// important line here
builder.addNetworkInterceptor(LoggerInterceptor());
Catluc
źródło
1

Większość odpowiedzi tutaj obejmuje prawie wszystko oprócz tego narzędzia, co jest jednym z najfajniejszych sposobów wyświetlania dziennika.

To jest Stetho na Facebooku . To doskonałe narzędzie do monitorowania / rejestrowania ruchu sieciowego Twojej aplikacji w Google Chrome . Można również znaleźć tutaj na Github.

wprowadź opis zdjęcia tutaj

Nishant Shah
źródło
1

dla Retrofit 2.0.2 kod jest podobny

   **HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient.Builder httpClient=new OkHttpClient.Builder();
        httpClient.addInterceptor(logging);**


        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    **.client(httpClient.build())**
                    .build();
        }
inny wysoki facet
źródło
1

Oto prosty sposób na filtrowanie dowolnych parametrów żądania / odpowiedzi z dzienników przy użyciu HttpLoggingInterceptor:

// Request patterns to filter
private static final String[] REQUEST_PATTERNS = {
    "Content-Type",
};
// Response patterns to filter
private static final String[] RESPONSE_PATTERNS = {"Server", "server", "X-Powered-By", "Set-Cookie", "Expires", "Cache-Control", "Pragma", "Content-Length", "access-control-allow-origin"};

// Log requests and response
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
    @Override
    public void log(String message) {

        // Blacklist the elements not required
        for (String pattern: REQUEST_PATTERNS) {
            if (message.startsWith(pattern)) {
                return;
            }
        }
        // Any response patterns as well...
        for (String pattern: RESPONSE_PATTERNS) {
            if (message.startsWith(pattern)) {
                return;
            }
        }
        Log.d("RETROFIT", message);
    }
});
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

Oto pełna treść:

https://gist.github.com/mankum93/179c2d5378f27e95742c3f2434de7168

miazga
źródło
1

setLevel()Utknąłem również w podobnej sytuacji, metoda nie nadchodziła, gdy próbowałem ją wywołać za pomocą instancji HttpLoggingInterceptor, jak poniżej:

HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

Oto jak to rozwiązałem, aby wygenerować dziennik dla Retrofit2,

Przypuszczam, że dodałeś zależność,

implementation "com.squareup.okhttp3:logging-interceptor:4.7.2"

Najnowszą wersję można sprawdzić, ten link:

https://github.com/square/okhttp/tree/master/okhttp-logging-interceptor )

Tutaj wyjaśnili także, jak dodać.

Stworzyłem klasę z imieniem AddLoggingInterceptor, oto mój kod,

public class AddLoggingInterceptor {

    public static OkHttpClient setLogging(){
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(loggingInterceptor)
                .build();

        return okHttpClient;
    }
}

Następnie, gdy tworzymy instancję naszego Modernizacji,

 public static Retrofit getRetrofitInstance() {
    if (retrofit == null) {
        retrofit = new retrofit2.Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(AddLoggingInterceptor.setLogging()) // here the method is called inside client() method, with the name of class, since it is a static method.
                .build();
    }
    return retrofit;
}

Teraz możesz zobaczyć dziennik wygenerowany w Android Studio, być może będziesz musiał wyszukać okHttpproces filtrowania. To zadziałało dla mnie. Jeśli jakieś problemy możesz do mnie napisać tutaj.

Jwala Kumar
źródło
0

Znalazłem sposób na Print Log in Retrofit

OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request request = chain.request();
                    if (BuildConfig.DEBUG) {
                        Log.e(getClass().getName(), request.method() + " " + request.url());
                        Log.e(getClass().getName(), "" + request.header("Cookie"));
                        RequestBody rb = request.body();
                        Buffer buffer = new Buffer();
                        if (rb != null)
                            rb.writeTo(buffer);
                        LogUtils.LOGE(getClass().getName(), "Payload- " + buffer.readUtf8());
                    }
                    return chain.proceed(request);
                }
            })
            .readTimeout(60, TimeUnit.SECONDS)
            .connectTimeout(60, TimeUnit.SECONDS)
            .build();

            iServices = new Retrofit.Builder()
                    .baseUrl("Your Base URL")
                    .client(okHttpClient)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build()
                    .create(Your Service Interface .class);

Pracuje dla mnie.

Nilesh Senta
źródło
0

Retrofit przechwytujący to świetna funkcja, która pozwala pracować z żądaniami HTTP. Istnieją dwa ich rodzaje: przechwytywacze aplikacji i sieci.

Polecam użyć, Charles Web Debugging Proxy Applicationjeśli potrzebujesz rejestrować swoje żądania / odpowiedzi. Dane wyjściowe są bardzo podobne do Stetho, ale jest to mocniejszy instrument, którego nie trzeba dodawać jako zależności do aplikacji

yoAlex5
źródło
-11

cześć chłopaki, już znalazłem rozwiązanie:

  public static <T> T createApi(Context context, Class<T> clazz, String host, boolean debug) {
    if (singleton == null) {
        synchronized (RetrofitUtils.class) {
            if (singleton == null) {
                RestAdapter.Builder builder = new RestAdapter.Builder();
                builder
                        .setEndpoint(host)
                        .setClient(new OkClient(OkHttpUtils.getInstance(context)))
                        .setRequestInterceptor(RequestIntercepts.newInstance())
                        .setConverter(new GsonConverter(GsonUtils.newInstance()))
                        .setErrorHandler(new ErrorHandlers())
                        .setLogLevel(debug ? RestAdapter.LogLevel.FULL : RestAdapter.LogLevel.NONE)/*LogLevel.BASIC will cause response.getBody().in() close*/
                        .setLog(new RestAdapter.Log() {
                            @Override
                            public void log(String message) {
                                if (message.startsWith("{") || message.startsWith("["))
                                    Logger.json(message);
                                else {
                                    Logger.i(message);
                                }
                            }
                        });
                singleton = builder.build();
            }
        }
    }
    return singleton.create(clazz);
}
Vihuela Yao
źródło
Oddzwonienie setLog może wprowadzać każdy dziennik
Vihuela Yao,
1
używa się modernizacji v1, a nie v2
Gabor,