0

Good day, so my problem as follows. When I initialize the retrofit call it has following flow.

1.In the Presenterclass, it goes to getData method.

2.Then it goes to Interactorclass and creates a instance of itself.

3.Then it starts to fetch data from getMovieList method.

4.When it gets to call.enqueue it says OnDataCallback is null.

5.Goes back to Presenter and returns a null List.

6.It resumes call.enqueue does the api call as required.

7.Returns to Presenter and returns the List of objects.

I have tried so many things but non seem to work, maybe I'm understanding something incorrectly ,any help would be appreciated thanks.

Interactor Class.

public class MovieListInteractor implements IMovieContarctor.MovieListInteractor {

    private InteractorListener mListener;
    private List<MovieListModel> mList;

    public MovieListInteractor(InteractorListener mListener) {
        this.mListener = mListener;
    }

    public int getMovieSize() {
        return mList.size();
    }

    @Override
    public String getMoviePosterPath(int pos) {
        return mList.get(pos).getPosterPath();
    }

    @Override
    public MovieListModel getMovie(int pos) {
        return mList.get(pos);
    }

    @Override
    public List<MovieListModel> getMovieList() {
        if (mList == null)
            mList = new ArrayList<>();
        ServerMovieCall mCall = new ServerMovieCall();
        mCall.getMovieList(new IOnDataCallback<List<MovieListModel>>() {
            @Override
            public void onSuccess(List<MovieListModel> data) {
                mList.addAll(data);
            }

            @Override
            public void onFailure(String message) {
                Log.d(TAG, "onFailure: " + message);
            }
        });
        return mList;
    }
}

Presenter class

public class MovieListPresenter implements IMovieContarctor.MovieListPresenter, InteractorListener {

    private MovieListFragment mView;
    private MovieListInteractor mInteractor;
    private List<MovieListModel> mList;

    public MovieListPresenter(MovieListFragment mView) {
        this.mView = mView;
        mInteractor = new MovieListInteractor(this);
        getData();

    }

    //TODO: Add functionality so that the view could call mView.refreshAdapterList
    //TODO: And from the view - adapter.notifiyDataSetChange;

    @Override
    public void onSuccess(List<MovieListModel> data, String msg) {
        mView.onDataChange(data, msg);
    }

    @Override
    public void onFailure(String msg) {
        mView.onDataFailure(msg);
    }

    @Override
    public void bindAtPosition(int position, MovieListViewHolder holder) {
        holder.setValue(mInteractor.getMovie(position));
    }

    @Override
    public void getData() {
        mList = mInteractor.getMovieList();
    }

    @Override
    public String getMoviePosterPath(int pos) {
        return mInteractor.getMoviePosterPath(pos);
    }

    @Override
    public int getSize() {
        return mInteractor.getMovieSize();
    }
}

Adapter

public class MovieListAdapter extends RecyclerView.Adapter<MovieListViewHolder> {
    private MovieListPresenter mPresenter;
    private Context ctx;

    public MovieListAdapter(MovieListPresenter mPresenter, Context context) {
        this.mPresenter = mPresenter;
        this.ctx = context;
    }

    @Override
    public MovieListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new MovieListViewHolder(LayoutInflater.from(ctx).inflate(R.layout.main_view_movie_list, parent, false));
    }

    @Override
    public void onBindViewHolder(MovieListViewHolder holder, int position) {
        mPresenter.bindAtPosition(position, holder);
        String image_url = IMAGE_URL_BASE_PATH + mPresenter.getMoviePosterPath(position);
        Picasso.with(ctx).load(image_url).placeholder(android.R.drawable.sym_def_app_icon)
                .error(android.R.drawable.sym_def_app_icon).into(holder.mImage);
    }

    @Override
    public int getItemCount() {
        return mPresenter.getSize();
    }
}

MovieCall class

public class ServerMovieCall {
    private Retrofit retrofit;
    private static ServerMovieCall mInstance;
    private Context ctx;

    public static ServerMovieCall getInstance() {
        if (mInstance == null) {
            mInstance = new ServerMovieCall();
        }
        return mInstance;
    }

    public ServerMovieCall() {
        configureClient();
    }

    private void configureClient() {
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder().addInterceptor(logging).addInterceptor(new Interceptor() {
            @Override
            public okhttp3.Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                HttpUrl url = request.url().newBuilder().addQueryParameter("api_key", Constants.API_KEY).build();
                request = request.newBuilder().url(url).build();

                return chain.proceed(request);
            }
        }).build();

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

    public void getMovieList(final IOnDataCallback<List<MovieListModel>> onDataCallback) {
        IServerMovieApiHelper iMovieReviewApiService = retrofit.create(IServerMovieApiHelper.class);
        Call<MovieListResponse> call = iMovieReviewApiService.getMovieList();
        call.enqueue(new Callback<MovieListResponse>() {
            @Override
            public void onResponse(Call<MovieListResponse> call, Response<MovieListResponse> response) {
                if (response.isSuccessful()) {
                    onDataCallback.onSuccess(response.body().getMovies());
                } else {
                    onDataCallback.onFailure(response.message());
                }
            }

            @Override
            public void onFailure(Call<MovieListResponse> call, Throwable t) {
                onDataCallback.onFailure(t.getLocalizedMessage());
            }
        });
    }

Contract interfaces

public interface IMovieContarctor {
    public interface MovieListInteractor {
        List<MovieListModel> getMovieList();

        MovieListModel getMovie(int pos);

        String getMoviePosterPath(int pos);
    }

    public interface MovieListPresenter {
        void bindAtPosition(int position, MovieListViewHolder holder);

        String getMoviePosterPath(int pos);

        int getSize();

        void getData();
    }

    public interface MovieListView {
        void onDataChange(List<MovieListModel> data, String message);

        void onDataFailure(String message);
    }
}

DataCallback Listener.

public interface IOnDataCallback<T> {
    void onSuccess(T data);
    void onFailure(String message);
}
udit7395
  • 626
  • 5
  • 16

1 Answers1

1

In Interactor class:

@Override
public List<MovieListModel> getMovieList() {
    if (mList == null)
        mList = new ArrayList<>();
    ServerMovieCall mCall = new ServerMovieCall();
    mCall.getMovieList(new IOnDataCallback<List<MovieListModel>>() {
        @Override
        public void onSuccess(List<MovieListModel> data) {
            mList.addAll(data);
            mListener.onSuccess(mList, "Your message");
        }

        @Override
        public void onFailure(String message) {
            Log.d(TAG, "onFailure: " + message);
        }
    });
    return mList;
}

In Presenter class:

@Override
public void onSuccess(List<MovieListModel> data, String msg) {
    mList = data;
    mView.onDataChange(data, msg);
}
Sotin Semyon
  • 131
  • 1
  • 5