Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Service methods cannot return void. retrofit

Tags:

retrofit

This is my method in Interface. I am calling this function but app crash with this exception:

Caused by: java.lang.IllegalArgumentException: Service methods cannot return void. for method RestInterface.getOtp

//post method to get otp for login
@FormUrlEncoded
@POST("/store_login")
void getOtp(@Header("YOUR_APIKEY") String apikey, @Header("YOUR_VERSION") String appversion,
            @Header("YOUR_VERSION") String confiver, @Field("mobile") String number, Callback<Model> cb);

And this is the code where I am calling this function

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(API_URL)
            .build();

    RestInterface restApi = retrofit.create(RestInterface.class);
    restApi.getOtp("andapikey", "1.0", "1.0", "45545845454", new Callback<Model>() {

        @Override
        public void onResponse(Response<Model> response) {

        }

        @Override
        public void onFailure(Throwable t) {

        }
    });
like image 574
kundan roy Avatar asked Aug 31 '15 12:08

kundan roy


4 Answers

There is difference in Asynchronous in Retrofit 1.9 and 2.0

/* Synchronous in Retrofit 1.9 */

public interface APIService {

@POST("/list")
Repo loadRepo();

}

/* Asynchronous in Retrofit 1.9 */

public interface APIService {

@POST("/list")
void loadRepo(Callback<Repo> cb);

}

But on Retrofit 2.0, it is far more simple since you can declare with only just a single pattern

/* Retrofit 2.0 */

public interface APIService {

@POST("/list")
Call<Repo> loadRepo();

}

// Synchronous Call in Retrofit 2.0

Call<Repo> call = service.loadRepo();
Repo repo = call.execute();

// Asynchronous Call in Retrofit 2.0

Call<Repo> call = service.loadRepo();
call.enqueue(new Callback<Repo>() {
@Override
public void onResponse(Response<Repo> response) {

   Log.d("CallBack", " response is " + response);
}

@Override
public void onFailure(Throwable t) {

  Log.d("CallBack", " Throwable is " +t);
}
});
like image 149
Mehrdad Faraji Avatar answered Nov 11 '22 13:11

Mehrdad Faraji


You can always do:

@POST("/endpoint")
Call<Void> postSomething();

EDIT:

If you are using RxJava, since 1.1.1 you can use Completable class.

like image 21
rafakob Avatar answered Nov 11 '22 14:11

rafakob


https://github.com/square/retrofit/issues/297

Please go through this link.

"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."

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

Based on the new Retrofit 2.0.0 beta You cannot specify return type as void to make it asynchronous

as per the code inside retrofit (https://github.com/square/retrofit/blob/master/retrofit/src/main/java/retrofit/MethodHandler.java) it will show exception when you try the previous implementation with 2.0.0 beta

if (returnType == void.class) {
throw Utils.methodError(method, "Service methods cannot return void.");
}
like image 4
Dennis MP Avatar answered Nov 11 '22 12:11

Dennis MP


Based on your classes, it looks like you are using Retrofit 2.0.0, which is currently in beta. I think using a void in your service method is no longer allowed. Instead, return Call, which you can enqueue to perform the network call asynchronously.

Alternatively, drop your library down to Retrofit 1.9.0 and replace your Retrofit class with RestAdapter.

like image 2
Tykin Avatar answered Nov 11 '22 13:11

Tykin