A type-safe HTTP client for Android and the JVM

Overview

Retrofit

A type-safe HTTP client for Android and Java.

For more information please see the website.

Download

Download the latest JAR or grab from Maven central at the coordinates com.squareup.retrofit2:retrofit:2.9.0.

Snapshots of the development version are available in Sonatype's snapshots repository.

Retrofit requires at minimum Java 8+ or Android API 21+.

R8 / ProGuard

If you are using R8 the shrinking and obfuscation rules are included automatically.

ProGuard users must manually add the options from retrofit2.pro. You might also need rules for OkHttp and Okio which are dependencies of this library.

License

Copyright 2013 Square, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Retrofit 2.0 API Spec (Working Draft)

    Retrofit 2.0 API Spec (Working Draft)

    This is a living spec for what will be v2 of Retrofit.

    Goals

    • Broaden the scope of how you can process successful responses and handle the results of various exceptions throughout the stack. Currently there's a mix of exceptions, wrapped types, and callbacks depending on the usage of synchronous or asynchronous API declarations.
    • Unify API declaration so that both synchronous and asynchronous consumption of a resource does not change its declaration.
    • Introduce better request and response interceptors which allow for both tweaks to existing requests or full on replacement (e.g., for signing purposes).
    • Allow simple request retry and cancel support without the need to talk to the RestAdapter or generated interface instance.
    • Completely decouple interface declaration parsing from request invocation and processing and expose the shim layer between the two as a extension-based system for customization. This will be used to (hopefully) facilitate RxJava integration as an extensions rather than being baked into the core of the library itself

    Changes

    Annotation Processors

    An annotation processor will be embedded inside the core artifact for compile-time verification of REST API interface declarations.

    A second annotation processor will be provided as a separate artifact for full code generation of a class implementation of each API interface.

    The RestAdapter will always do a read-through cached lookup for the generated classes since it has no knowledge of whether the code-gen processor was used and we don't want to place the burden on the caller either.

    Request Object

    All interface declarations will be required to return an object through which all interaction will occur. The behavior of this object will be similar to a Future and will be generic typed (T) for the success response type (ref: #231).

    @GET("/foo")
    Call<Foo> getFoo();
    

    Callers can synchronously call .execute() which will return type T. Exceptions will be thrown for any error, network error, unsuccessful response, or unsuccessful deserialization of the response body. While these exceptions will likely extend from the same supertype, it's unclear as to whether that supertype should be checked or unchecked.

    interface Api {
      @GET("/{user}/tweets")
      Call<List<Tweet>> listTweets(@Path("user") String username);
    }
    
    List<Tweet> tweets = api.listTweets("JakeWharton").execute();
    

    Callers can also supply callbacks to this object for asynchronous notification of the response. The traditional Callback<T> of the current version of Retrofit will be available. One change will be that the error object passed to failure will not be the same exception as would be thrown in synchronous execution but rather something a bit more transparent to the underlying cause.

    interface Api {
      @GET("/{user}/tweets")
      Call<List<Tweet>> listTweets(@Path("user") String username);
    }
    
    Call<List<Tweet>> c = api.listTweets("JakeWharton");
    c.execute(new Callback<List<Tweet>>() {
      @Override public void success(List<Tweet> response) { }
      // ...
    }
    

    TODO describe error handling

    public abstract class ResponseCallback<T> {
      public abstract void success(T response);
    
      public void networkError(IOException e) {
        error(ErrorType.NETWORK, -1, e);
      }
      public void processingError(Exception e) {
        error(ErrorType.PROCESSING, -1, e);
      }
      public void httpError(int status, ...) {
        error(ErrorType.HTTP, status, e);
      }
      public void error(ErrorType errorType, int status, Exception e) {
        throw new RuntimeException(.., e);
      }
    
      public enum ErrorType { NETWORK, PROCESSING, HTTP }
    }
    

    The call object is also an obvious place for handling the retry and cancelation of requests. Both are a simple, no-args method on the object which can only be called at appropriate times.

    • cancel() is a no-op after the response has been received. In all other cases the method will set any callbacks to null (thus freeing strong references to the enclosing class if declared anonymously) and render the request object dead. All future interactions with the request object will throw an exception. If the request is waiting in the executor its Future will be cancelled so that it is never invoked.
    • retry() will re-submit the request onto the backing executor without passing through any of the mutating pipeline described above. Retrying a request is only available after a network error or 5XX response. Attempting to retry a request that is currently in flight, after a non-5XX response, after an unexpected error, or after calling cancel() will throw an exception.

    Extension System

    In order to facilitate libraries which offer semantics on both synchronous and asynchronous operations without requiring a wrapper, we will introduce a system which we will tentatively refer to as extensions. An extension instance will be registered with the RestAdapter and associate itself as handling an explicit interface method return type.

    By default, Retrofit will install its own extension which handles the aforementioned Call type for both synchronous and asynchronous request execution.

    The current (albeit experimentally denoted) RxJava integration will also be provided as an opt-in extension. This extension will register itself as handling the Observable type which will allow the declaration of interfaces which return this type.

    interface FooService {
      @GET("/foos")
      Observable<Foo> getFoo();
    }
    

    And more...

    TODO!

    opened by JakeWharton 106
  • How to Upload a File using Retrofit 2.0

    How to Upload a File using Retrofit 2.0

    How to upload a file using multipart/form-data upload in Retrofit 2.0, I am unable to upload and there is no proper documentation anywhere on uploading file using retrofit 2.0, I followed the docs in retrofit website but I was not able to make it work.

    All the examples I see used TypedFile. It is not clear how to use RequestBody. Please post sample code.

    opened by vivekkiran 100
  • 1.4.0 New line in String causes retrofit.RetrofitError: java.io.EOFException

    1.4.0 New line in String causes retrofit.RetrofitError: java.io.EOFException

    Gist: https://gist.github.com/mazurio/8750846

    Description is a text taken from TextView (Android), if it contains more than one new line then it causes EOFException and insert fails. Trying to figure it out now.

    I tried to escape the string. It is the same problem.

    opened by mazurio 59
  • Handle Empty Body

    Handle Empty Body

    After updating to retrofit beta-3 I'm getting the Exception (Because of an empty body)

    java.io.EOFException: End of input at line 1 column 1
                                                                               at com.google.gson.stream.JsonReader.nextNonWhitespace(JsonReader.java:1414)
                                                                               at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:553)
                                                                               at com.google.gson.stream.JsonReader.peek(JsonReader.java:429)
                                                                               at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:202)
                                                                               at com.google.gson.TypeAdapter.fromJson(TypeAdapter.java:260)
                                                                               at retrofit2.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:33)
                                                                               at retrofit2.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:23)
                                                                               at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:154)
                                                                               at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:92)
                                                                               at okhttp3.RealCall$AsyncCall.execute(RealCall.java:133)
    

    I know that It's possible to solve this issue Using Call<Void> but is there any other way to enforce OkHttp or Gson To accept Empty body?

    Response Log:

     D/OkHttp: Date: Mon, 01 Feb 2016 08:32:10 GMT
    D/OkHttp: Server: Apache/2.4.7 (Ubuntu)
    D/OkHttp: X-Powered-By: PHP/5.5.9-1ubuntu4.13
    D/OkHttp: Expires: Thu, 19 Nov 1981 08:52:00 GMT
    D/OkHttp: Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    D/OkHttp: Pragma: no-cache
    D/OkHttp: Access-Control-Allow-Origin: https://example.com
    D/OkHttp: Access-Control-Allow-Methods: GET,POST,OPTIONS
    D/OkHttp: Access-Control-Allow-Headers: Accept,Cache-Control,Pragma,Origin,Authorization,Content-Type,X-Requested-With,Cookie,*
    D/OkHttp: Access-Control-Allow-Credentials: true
    D/OkHttp: Content-Length: 0
    D/OkHttp: Keep-Alive: timeout=5, max=99
    D/OkHttp: Connection: Keep-Alive
    D/OkHttp: Content-Type: application/json
    D/OkHttp: OkHttp-Sent-Millis: 1454315528548
    D/OkHttp: OkHttp-Received-Millis: 1454315528725
    D/OkHttp: <-- END HTTP (0-byte body)
    
    opened by roybrener 40
  • Allow to configure retrofit to allow API interfaces to extend interfaces

    Allow to configure retrofit to allow API interfaces to extend interfaces

    The comment:

    // Prevent API interfaces from extending other interfaces. This not only avoids a bug in
    // Android (http://b.android.com/58753) but it forces composition of API declarations which is
    // the recommended pattern.
    

    in:

    https://github.com/square/retrofit/blob/master/retrofit/src/main/java/retrofit/Utils.java

    Sounds rather arbitrary. I think it should be configurable at the very least.

    I for example have something very similar to the following.

    A base response class:

    class GenericResponse {
       Boolean success
    }
    

    and an interface that defines how my API needs to be accessed:

    interface GenericAPI<R extends GenericResponse> {
       void obtainData(
          String name, String version, Map<String, String> parameters, Callback<R> callback
       )
    }
    

    I latter extend that interface with some specific API like:

    interface GetUsersAPI extends GenericAPI<UsersResponse> {
       @GET("/dataAPI/{version}/{name}")
       void obtainData(
          @Path("name") String name,
          @Path("version") String version,
          @QueryMap Map<String, String> parameters,
          Callback<UsersResponse> callback
       )
    }
    

    being UsersResponse an extension of GenericResponse. With something like that, I can implement an abstract client like:

    abstract class GenericClient<R extends GenericResponse, C extends GenericConnector> implements Callback<R> { 
    
       protected void doRequest(
          Class<C> apiDefinition, 
          String name, String version, 
          Map<String, Object> params
       ) { 
          new RestAdapter.Builder().build().create(apiDefinition).obtainData(
             name, version, params, this
          )
       }
    }
    

    That client can work with any of my APIs, avoiding code duplication while having typing enforced by the compiler using generics. It can deal with any obtainData connector and with the common parts of every response. When implemented by a concrete class, thanks to the use of generics and inheritance, the data is transformed to the proper specific response class and when using an IDE with generics support (any, I guess :) is very convenient to use every method with the signature automatically transformed to the concrete classes declared by the implementor class.

    I understand that composition is better for many things, but I don't see how to work with a generic connector the way I'm doing it, being able to assume that every connector will have an obtainData with the given parameters and having that enforced by the compiler.

    I'm not saying is not possible - I'm saying I don't know how, and the restriction I'm finding is, in my opinion, quite poorly explained.

    I think something whose reason to be is something as arguable as "composition is the only possible, good way" should be configurable at least.

    Enhancement 
    opened by deigote 40
  • 2.0-beta2 adding extra quotes to multipart string form values

    2.0-beta2 adding extra quotes to multipart string form values

    retrofit 2.0 seems to be double quoting strings in multi part post requsts.

    for example this interface

    public interface ApiInterface {
    
        @Multipart
        @POST("user/login/")
        Call<SessionToken> userLogin(@Part("username") String username, @Part("password") String password);
    }
    

    server side will print the key value pairs as

    username : "brian"
    password : "password"
    

    instead of

    username : brian
    password : password
    

    The second way is how it would show up in retrofit 1.9 and any other rest client.

    stack link https://stackoverflow.com/questions/33205855/retrofit-2-0-beta-2-is-adding-literal-quotes-to-multipart-values?noredirect=1#comment54246402_33205855

    opened by bperin 38
  • Add a way to set filename on multipart requests

    Add a way to set filename on multipart requests

    This has already been discussed in #1063 #1092 #1096 and #1130, but I thought I'd open a separate issue to track this specifically.

    RFC2388 describes the filename header parameter of multipart/form-data requests that Retrofit now uses. This parameter is required on some backend configurations. More details and examples can be found here.

    We need a way of figuring out what the filename is. The problem with RequestBody (which is a part of OkHttp) is that it doesn't expose the filename when created with a File.

    Feature 
    opened by lukaciko 37
  • RxJava Retrofit --Fatal Exception thrown on Scheduler.Worker thread.

    RxJava Retrofit --Fatal Exception thrown on Scheduler.Worker thread.

    ApiManager.getApi().dispatchService(SPUtils.getUserId(), groupType) .observeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new ResultSubscriber() { @Override public void onSuccess(ServiceResultBean serviceResultBean) {

                        }
    
                        @Override
                        public void onError(ResultException error) {
                            name.setText(error.getMessage());
                        }
    
                        @Override
                        public void onCompleted() {
                            loading.setVisibility(View.GONE);
                        }
                    });
    

    then... E/AndroidRuntime﹕ FATAL EXCEPTION: main java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread. at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62) at android.os.Handler.handleCallback(Handler.java:615) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4745) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method) Caused by: rx.exceptions.OnErrorFailedException: Error occurred when trying to propagate error to Observer.onError at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:201) at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:111) at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:197) at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:170) at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)             at android.os.Handler.handleCallback(Handler.java:615)             at android.os.Handler.dispatchMessage(Handler.java:92)             at android.os.Looper.loop(Looper.java:137)             at android.app.ActivityThread.main(ActivityThread.java:4745)             at java.lang.reflect.Method.invokeNative(Native Method)             at java.lang.reflect.Method.invoke(Method.java:511)             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)             at dalvik.system.NativeStart.main(Native Method) Caused by: rx.exceptions.CompositeException: 2 exceptions occurred.             at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:201)             at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:111)             at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:197)             at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:170)             at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)             at android.os.Handler.handleCallback(Handler.java:615)             at android.os.Handler.dispatchMessage(Handler.java:92)             at android.os.Looper.loop(Looper.java:137)             at android.app.ActivityThread.main(ActivityThread.java:4745)             at java.lang.reflect.Method.invokeNative(Native Method)             at java.lang.reflect.Method.invoke(Method.java:511)             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)             at dalvik.system.NativeStart.main(Native Method) Caused by: rx.exceptions.CompositeException$CompositeExceptionCausalChain: Chain of Causes for CompositeException In Order Received => at android.util.Log.getStackTraceString(Log.java:314) at android.util.Slog.e(Slog.java:77) at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:72) at u.aly.n.uncaughtException(CrashHandler.java:34) at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693) at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690) at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:66)             at android.os.Handler.handleCallback(Handler.java:615)             at android.os.Handler.dispatchMessage(Handler.java:92)             at android.os.Looper.loop(Looper.java:137)             at android.app.ActivityThread.main(ActivityThread.java:4745)             at java.lang.reflect.Method.invokeNative(Native Method)             at java.lang.reflect.Method.invoke(Method.java:511)             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)             at dalvik.system.NativeStart.main(Native Method) Caused by: retrofit.RetrofitError at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:395) at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220) at retrofit.RestAdapter$RestHandler$1.invoke(RestAdapter.java:265) at retrofit.RxSupport$2.run(RxSupport.java:55) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) at java.util.concurrent.FutureTask.run(FutureTask.java:137) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) at retrofit.Platform$Android$2$1.run(Platform.java:142) at java.lang.Thread.run(Thread.java:856) Caused by: java.net.SocketTimeoutException at java.net.PlainSocketImpl.read(PlainSocketImpl.java:491) at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46) at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240) at okio.Okio$2.read(Okio.java:137) at okio.AsyncTimeout$2.read(AsyncTimeout.java:211) at okio.RealBufferedSource.indexOf(RealBufferedSource.java:306) at okio.RealBufferedSource.indexOf(RealBufferedSource.java:300) at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:196) at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191) at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80) at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:917) at com.squareup.okhttp.internal.http.HttpEngine.access$300(HttpEngine.java:95) at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:902) at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:760) at com.squareup.okhttp.Call.getResponse(Call.java:274) at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:230) at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:201) at com.squareup.okhttp.Call.execute(Call.java:81) at retrofit.client.OkClient.exec

    opened by cuimingqiang 37
  • method POST must have a request body.

    method POST must have a request body.

    Why?

    compile 'com.squareup.okhttp:okhttp:2.3.0'
    compile 'com.squareup.retrofit:retrofit:1.9.0'
    
                         D  java.lang.IllegalArgumentException: method POST must have a request body.
                            D      at com.squareup.okhttp.Request$Builder.method(Request.java:236)
                            D      at retrofit.client.OkClient.createRequest(OkClient.java:59)
                            D      at retrofit.client.OkClient.execute(OkClient.java:53)
                            D      at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326)
                            D      at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
                            D      at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278)
                            D      at retrofit.CallbackRunnable.run(CallbackRunnable.java:42)
                            D      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                            D      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                            D      at retrofit.Platform$Android$2$1.run(Platform.java:142)
                            D      at java.lang.Thread.run(Thread.java:818)
    
    opened by crossle 37
  • Add ErrorHandler for customization of RetrofitError behavior

    Add ErrorHandler for customization of RetrofitError behavior

    Add a new interface, ErrorHandler, which is responsible for throwing customized exceptions during synchronous request errors, or directing to the appropriate callback method for asynchronous request errors.

    Currently, API users must catch RetrofitError and try to determine the cause of the error based on certain properties of the HTTP response. This interface allows API clients to expose semantic exceptions to their users.

    For example, if I had an API interface method to create a User, I might expose an InvalidUserException which could be declared on the createUser method, and used to indicate that something was invalid about the request.

    This implementation allows exceptions to be checked or unchecked, leaving that decision up to the API designer. It also doesn't change any existing behavior. Let me know if there's anything I can do to clean it up!

    opened by sberan 37
  • FATAL EXCEPTION: OkHttp Dispatcher with okhttp:3.0.0

    FATAL EXCEPTION: OkHttp Dispatcher with okhttp:3.0.0

    My setup without the problem:

    compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
    compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3'
    compile 'com.squareup.okhttp3:okhttp:3.0.0-RC1'
    

    My setup wit the problem and no code changes:

    compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
    compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3'
    compile 'com.squareup.okhttp3:okhttp:3.0.0'
    

    Produces following error:

    FATAL EXCEPTION: OkHttp Dispatcher
        Process: com.my.app, PID: 31176
        java.lang.AbstractMethodError: abstract method "void okhttp3.Callback.onResponse(okhttp3.Call, okhttp3.Response)"
          at okhttp3.RealCall$AsyncCall.execute(RealCall.java:133)
          at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:33)
          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
          at java.lang.Thread.run(Thread.java:818)
    
    opened by artworkad 34
  • Is it possible to parse annotations in the phase real executing request?

    Is it possible to parse annotations in the phase real executing request?

    • [ ] Feature Request. Retrofit#loadServiceMethod does parsing annotations of method and method parameters, sometimes developer maybe call service in the main thread in Android which may cause laggy when executing java reflection while a method has lots of parameters. To avoid this, if we can move parsing annotations in the phase real executing request(must in other thread in Android), so we will not block the main thread which can make app running more fluently.
    opened by ParadiseHell 0
  • Add ability to set base url per service

    Add ability to set base url per service

    I found this feature - https://github.com/square/retrofit/issues/2180#issuecomment-327833876 to be useful in android apps. For example, when backend team decided to move and maybe refactor their code to other remote. And it's not one day change, so android app need to use two base urls - old one and new one. It can be done with prepending base url per each request for new service or use 2 retrofit instances. I'd not consider 2nd solution at all because it's not memory efficient + service creation pattern is error prone - you can accidentally create service from wrong retrofit instance. 1st solution works, but it requires lot of base url duplicates.

    From other side this feature can be used in proxy servers, that use multiple remotes to fetch/operate.

    PS.: I didn't completely understood from linked comment if you consider these use cases as valid, so please, accept my apologies if I missed something from this long v3 thread. But I don't see any pitfalls in changes made to support this feature, so I created this PR 😄

    opened by agamula90 0
  • SocketTimeoutException And App crash

    SocketTimeoutException And App crash

    What kind of issue is this?

    • [ ] java.net.SocketTimeoutException: failed to connect to ** after 10000ms at libcore.io.IoBridge.connectErrno(IoBridge.java:190) at libcore.io.IoBridge.connect(IoBridge.java:134) at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:142) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436) at java.net.Socket.connect(Socket.java:631) at okhttp3.internal.platform.Platform.connectSocket(Platform.kt:128) at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.kt:295) at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:207) at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:226) at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106) at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74) at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255) at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:221) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109) at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201) at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:517) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:923) Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [CoroutineId(171), "coroutine#171":StandaloneCoroutine{Cancelling}@ea0834a, Dispatchers.Main.immediate]

    • [ ] open fun launch(block: suspend () -> Unit, error: suspend (Throwable) -> Unit) = viewModelScope.launch { try { block() } catch (e: Throwable) { error(e) //if app crash ,this catch not working! } }

    • [ ] implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.okhttp3:logging-interceptor:4.10.0'

    opened by wuhuaqing 1
  • Crash with R8 full mode enabled with generics and Rx

    Crash with R8 full mode enabled with generics and Rx

    Retrofit: 2.9.0

    The crashing retrofit interface contains methods like these:

        @FormUrlEncoded
        @POST("token/oauth2")
        fun clientCredentials(
            @Field("client_id") clientId: String,
            @Field("client_secret") clientSecret: String,
            @Field("grant_type") @SupportedGrantType grantType: String = SupportedGrantType.CLIENT_CREDENTIALS
        ): Single<Response<JWTEnvelope>>
    

    where JWTEnvelope is my own class:

    @Keep // androidx.annotation
    @JsonClass(generateAdapter = true)
    data class JWTEnvelope(
        @Json(name = "access_token")
        val accessToken: String,
        @Json(name = "token_type")
        @SupportedTokenType
        val tokenType: String,
        @Json(name = "expires_in")
        val expiresIn: Int,
        @Json(name = "refresh_token")
        val refreshToken: String? = null
    )
    

    I'm not sure if this is the same thing that is being discussed here https://github.com/square/retrofit/issues/3588. But I have the @Keep annotation so this should work if the issue is the one described there, isn't it?

    I get

    java.lang.RuntimeException: Unable to start activity ComponentInfo{my.app/my.app.home.HomeActivity}: java.lang.IllegalArgumentException: Unable to create call adapter for class lj.u
    [...]
    Caused by: java.lang.IllegalArgumentException: Unable to create call adapter for class lj.u
        for method j.a
    	at retrofit2.Utils.methodError(Utils.java:54)
    	at retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:116)
    	at retrofit2.HttpServiceMethod.parseAnnotations(HttpServiceMethod.java:67)
    	at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:39)
    	at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:202)
    	at retrofit2.Retrofit$1.invoke(Retrofit.java:160)
    	at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
    	at $Proxy5.a(Unknown Source)
    	at my.app.auth.oauth2.OAuth2RestAPI$DefaultImpls.clientCredentials$default(OAuth2RestAPI.kt:18)
    [...]
    Caused by: java.lang.IllegalStateException: Single return type must be parameterized as Single<Foo> or Single<? extends Foo>
    	at retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory.get(RxJava2CallAdapterFactory.java:118)
    	at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:253)
    	at retrofit2.Retrofit.callAdapter(Retrofit.java:237)
    	at retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:114)
    	... 81 more
    

    The Single class is the one that can't be mapped apparently: io.reactivex.Single -> lj.u.

    Am I supposed to just keep every Single class? or is there a better way?

    Thanks

    opened by danielesegato 4
  • Integrating retrofit into OSS-Fuzz

    Integrating retrofit into OSS-Fuzz

    Hi all,

    We have prepared the initial integration of retrofit into Google OSS-Fuzz which will provide more security for your project.

    Why do you need Fuzzing? The Code Intelligence JVM fuzzer Jazzer has already found hundreds of bugs in open source projects including for example OpenJDK, Protobuf or jsoup. Fuzzing proved to be very effective having no false positives. It provides a crashing input which helps you to reproduce and debug any finding easily. The integration of your project into the OSS-Fuzz platform will enable continuous fuzzing of your project by Jazzer.

    What do you need to do? The integration requires the maintainer or one established project commiter to deal with the bug reports.

    You need to create or provide one email address that is associated with a google account as per here. When a bug is found, you will receive an email that will provide you with access to ClusterFuzz, crash reports, code coverage reports and fuzzer statistics. More than 1 person can be included.

    How can Code Intelligence support you? We will continue to add more fuzz targets to improve code coverage over time. Furthermore, we are permanently enhancing fuzzing technologies by developing new fuzzers and bug detectors.

    Please let me know if you have any questions regarding fuzzing or the OSS-Fuzz integration.

    Thank you!

    opened by henryrneh 0
Releases(parent-2.0.0-beta3)
Square’s meticulous HTTP client for the JVM, Android, and GraalVM.

OkHttp See the project website for documentation and APIs. HTTP is the way modern applications network. It’s how we exchange data & media. Doing HTTP

Square 43.4k Jan 5, 2023
Ktorfit - a HTTP client/Kotlin Symbol Processor for Kotlin Multiplatform (Js, Jvm, Android, iOS, Linux) using KSP and Ktor clients inspired by Retrofit

Ktorfit is a HTTP client/Kotlin Symbol Processor for Kotlin Multiplatform (Js, Jvm, Android, iOS, Linux) using KSP and Ktor clients inspired by Retrofit

Jens Klingenberg 637 Dec 25, 2022
Handle various HTTP status code by safe api call with Result sealed class

retrofit2-safe-api-call Handle various HTTP status code by safe api call with Result sealed class Library Retrofit2 OkHttp3 Gson Coroutine DI : Koin V

Jaesung Lee 2 May 16, 2022
LiteHttp is a simple, intelligent and flexible HTTP framework for Android. With LiteHttp you can make HTTP request with only one line of code! It could convert a java model to the parameter and rander the response JSON as a java model intelligently.

Android network framework: LiteHttp Tags : litehttp2.x-tutorials Website : http://litesuits.com QQgroup : 42960650 , 47357508 Android网络通信为啥子选 lite-htt

马天宇 829 Dec 29, 2022
Android Easy Http - Simplest android http request library.

Android Easy Http Library 繁體中文文檔 About Android Easy Http Library Made on OkHttp. Easy to do http request, just make request and listen for the respons

null 13 Sep 30, 2022
Asynchronous socket, http(s) (client+server) and websocket library for android. Based on nio, not threads.

AndroidAsync AndroidAsync is a low level network protocol library. If you are looking for an easy to use, higher level, Android aware, http request li

Koushik Dutta 7.3k Jan 2, 2023
Asynchronous Http and WebSocket Client library for Java

Async Http Client Follow @AsyncHttpClient on Twitter. The AsyncHttpClient (AHC) library allows Java applications to easily execute HTTP requests and a

AsyncHttpClient 6k Jan 8, 2023
An android asynchronous http client built on top of HttpURLConnection.

Versions 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 Version 1.0.6 Description An android asynchronous http client based on HttpURLConnection. Updates U

David 15 Mar 29, 2020
Multiplatform coroutine-based HTTP client wrapper for Kotlin

networkinkt This is a lightweight HTTP client for Kotlin. It relies on coroutines on both JS & JVM platforms. Here is a simple GET request: val text =

Egor Zhdan 31 Jul 27, 2022
Kotlin DSL http client

Introduction Kotlin DSL http client Features ?? Developers Experience-driven library without verbosity. ?? Native way to use http client in Kotlin. ??

Sergei Rybalkin 461 Dec 13, 2022
Unirest in Java: Simplified, lightweight HTTP client library.

Unirest for Java Install With Maven: <!-- Pull in as a traditional dependency --> <dependency> <groupId>com.konghq</groupId> <artifactId>unire

Kong 2.4k Jan 5, 2023
Unirest in Java: Simplified, lightweight HTTP client library.

Unirest for Java Install With Maven: <!-- Pull in as a traditional dependency --> <dependency> <groupId>com.konghq</groupId> <artifactId>unire

Kong 2.4k Dec 24, 2022
A gRPC Kotlin based server and client starter that builds with Gradle and runs on the JVM

gRPC Kotlin starter Overview This directory contains a simple bar service written as a Kotlin gRPC example. You can find detailed instructions for bui

Hypto 8 Sep 19, 2022
Note app that allows user to save/edit/delete/search any type of notes and view them in a list

NoteApp Note app that allows user to save/edit/delete/search any type of notes a

rıdvan 15 May 6, 2022
Monitoring water tanker level using NodeMCU ESP8266 and HC-SR04P Ultrasonic Sensor and broadcasting it using a simple HTTP server inside NodeMCU ESP8266 and show data in an Android App

WaterLevel Preface This project aims to finding a tanker water level using NodeMCU with ESP8266 core and HC-SR04P Ultrasonic sensor and broadcasting i

YaMiN 12 Dec 20, 2022
Pluto is a on-device debugger for Android applications, which helps in inspection of HTTP requests/responses, capture Crashes and ANRs and manipulating application data on-the-go.

Pluto Pluto is a on-device debugger for Android applications, which helps in inspection of HTTP requests/responses, capture Crashes and ANRs and manip

Mocklets 8 Aug 22, 2022
Volley is an HTTP library that makes networking for Android apps easier and, most importantly, faster.

Volley Volley is an HTTP library that makes networking for Android apps easier and, most importantly, faster. For more information about Volley and ho

Google 3.3k Jan 1, 2023
HttpMocker is a simple HTTP mocking library written in Kotlin to quickly and easily handle offline modes in your apps

HttpMocker HttpMocker is a very lightweight Kotlin library that allows to mock HTTP calls relying on either OkHttp or the Ktor client libraries. It ca

David Blanc 174 Nov 28, 2022
Allows recording and playback http request/responses for testing purposes.

Allows recording and playback http request/responses for testing purposes.

Cristian Gómez 4 Aug 4, 2022