Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrofit call inside AsyncTask

I've recently started developing an Android app and decided to use Retrofit as a client of a REST service, but I am not sure if my approach is good:

i. I've implemented an asynchronous call to my api, which is called inside AsyncTask's doInBackground method. The concern: having read this article got me confused. Aren't AsyncTasks suitable for this kind of tasks? Should I make the call to the API directly from the Activity? I understand that Retrofit's callback methods are executed on the UI thread, but how about the call over HTTP? Does Retrofit create threads for that?

ii. I want the AuthenticationResponse to be saved inside a SharedPreferences object, which doesn't seem to be available inside the success method of the callback. Any suggestions/ good practices?

Thank you in advance :)

Here's my doInBackGroundMethod:

    @Override
    protected String doInBackground(String... params) {
        Log.d(LOCATION_LOGIN_TASK_TAG, params[0]);

        LocationApi.getInstance().auth(new AuthenticationRequest(params[0]), new Callback<AuthenticationResponse>() {

            @Override
            public void success(AuthenticationResponse authenticationResponse, Response response) {
                Log.i("LOCATION_LOGIN_SUCCESS", "Successfully logged user into LocationAPI");
            }

            @Override
            public void failure(RetrofitError error) {
                Log.e("LOCATION_LOGIN_ERROR", "Error while authenticating user in the LocationAPI", error);
            }
        });
        return null;
    }
like image 907
user3159152 Avatar asked Mar 28 '15 21:03

user3159152


1 Answers

I. Retrofit supports three ways to make a request:

  • synchronic

You have to declare method which returns response as value for example:

  @GET("/your_endpoint")
  AuthenticationResponse auth(@Body AuthenticationRequest authRequest);

This method is done in the thread in which is called. So you can't call it in main/UI thread.

  • asynchronous

You have to declare void method which contains callback with response as last param for example:

  @GET("/your_endpoint")
  void auth(@Body AuthenticationRequest authRequest, Callback<AuthenticationResponse> callback);

The execution of request is called in new background thread and the callback methods are done in the thread which method is called, so you can call this method in main/UI thread without new thread/AsyncTask.

  • Using RxAndroid

The last way which I know is method which uses RxAndroid. You have to declare method which returns response as observable with value. For example:

  @GET("/your_endpoint")
  Observable<AuthenticationResponse> auth(@Body AuthenticationRequest authRequest);

This method also supports to make network request in new thread. So you don't have to create new thread/AsyncTask. The Action1 callback from subscribe method is called in UI/main thread.

II. You can call your method just in Activity and you can write your data to SharedPreferences as is shown below:

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
sharedPreferences.edit()
            .put...//put your data from AuthenticationResponse 
                   //object which is passed as params in callback method.
            .apply();
like image 112
Konrad Krakowiak Avatar answered Oct 19 '22 15:10

Konrad Krakowiak