Retrofit + Otto + AA, How to do simple get request

2019-09-21 10:13发布

问题:

I am using Android Annotation for boilerplate, and Retrofit for Api calls, While doing post requests through retrofit I discovered a Some problems:

When i am calling asynchronous call to "GET" request using Retrofit, I need to do some operation just after my call gets finished, and I can't use "onResponse()" because I am using "Bean" annotation

It doesn't make sense right? have a look on code

Example Bean class:

@EBean
public class someClass{

   /* Suppose api is getting RestClient reference from Retrofit*/
   @AfterInject
   void doSomeWork(){ api = SampleAPI.Factory.getIstance(mcontext);}

   /**
     * Get list of all courses from database
     * @Return List<CourseInfo> courseInfo objects
     */
    public List<CourseInfo> GetCoursesList() {
        final List<CourseInfo> cor = new ArrayList<>();
        api.getAllCourses(user.getApikey()).enqueue(new Callback<List<CourseInfo>>() {
            @Override
            public void onResponse(retrofit2.Call<List<CourseInfo>> call, Response<List<CourseInfo>> response) {
                Collections.copy(cor,response.body());
            }

            @Override
            public void onFailure(retrofit2.Call<List<CourseInfo>> call, Throwable t) {
                UiHelpers.showToast(mcontext,"Unable to get List of Course Names");
            }
        });
        return cor;
    }
} 

Calling in Activity something Like:

@EActivity(R.layout.something)
public class student extends AppCompatActivity {

    @Bean
    someClass some;

    @AfterViews
    void setInits(){

        course = cc.GetCoursesList();

        Toast.makeText(this,"Why this is running before getting all courses??",Toast.LENGTH_LONG).show();

    }
}

I want to know how can I improve this structure using Otto? v And why my this structure is failing?
Because I am unable to get coursesList from server!!

回答1:

Why this is running before getting all courses??

Because that's how asynchronous code works?

Retrofit is not a blocking call.

If you want to perform an action from onResponse back on the UI thread, you don't even need an EventBus library, just give the callback as the parameter of the method.

public void GetCoursesList(Callback<List<CourseInfo>> callback)  {
    api.getAllCourses(user.getApikey()).enqueue(callback);
} 

The method is now void because, again, Retrofit doesn't block, so you returned an empty list while the server request occurred

@AfterViews
void setInits(){

    cc.GetCoursesList(new Callback<List<CourseInfo>>() {
        // TODO: Implement the interface 
     } );

    Toast.makeText(this,"Why this is running before getting all courses??",Toast.LENGTH_LONG).show();

}