Проблема с использованием универсального типа в интерфейсе - PullRequest
0 голосов
/ 27 октября 2018

Я пытаюсь создать базовый вспомогательный класс для обработки всех вызовов API моего приложения, поэтому я написал его следующим кодом, но проблема в том, что при его вызове выдается предупреждение «Не проверен вызов onResponse (T) как член типа Raw "в строке 'taskListener.onResponse (response);' , Я знаю, что я не передаю тип в ApiTaskListener в методе executeApiCall, но если я использую 'ApiTaskListener', тогда он показывает ошибку в 'taskListener.onResponse (response);' и просит удалить универсальный тип из интерфейса ApiTaskListener и использовать тип в качестве объекта. Я не хочу использовать Object из-за наложения накладных расходов каждый раз в моем вызывающем методе. Любые предложения будут заметны.

метод вызова:

makeApiCall(request, new ApiTaskListener<PeopleResponse>() {
            @Override
            public void onResponse(PeopleResponse response) {

            }

            @Override
            public void onError(ApiError apiError) {

            }
        });

Код базового класса:

protected void makeApiCall(Single<?> request, ApiTaskListener<?> taskListener) {

        if (!NetworkUtils.isNetworkConnected(getResourceProvider().getContext())) {
            if (taskListener != null)
                taskListener.onError(new ApiError(410, getResourceProvider().getString(R.string.internet_error)));
            return;
        }

        getCurrentUserSession(new SessionListener() {
            @Override
            public void onSuccess() {
                executeApiCall(request, taskListener);
            }

            @Override
            public void onFailure(ApiError error) {
                if (taskListener != null)
                    taskListener.onError(error);
            }
        });

    }

    private void executeApiCall(Single<?> request, ApiTaskListener taskListener) {
        getCompositeDisposable().add(request
                .subscribeOn(getSchedulerProvider().io())
                .observeOn(getSchedulerProvider().ui())
                .subscribe((Consumer<Object>) response -> {
                    if (taskListener != null)
                        taskListener.onResponse(response);
                }, throwable -> {
                    if (taskListener != null)
                        taskListener.onError(AppApiHelper.parseApiError(throwable));
                }));
    }


    public interface ApiTaskListener<T>{
        void onResponse(T response);

        void onError(ApiError apiError);
    }

1 Ответ

0 голосов
/ 29 октября 2018

Примерно так должно работать (замена подстановочного знака <?> на <T>):

protected <T> void makeApiCall(Single<T> request, ApiTaskListener<T> taskListener) {

    if (!NetworkUtils.isNetworkConnected(getResourceProvider().getContext())) {
        if (taskListener != null)
            taskListener.onError(new ApiError(410, getResourceProvider().getString(R.string.internet_error)));
        return;
    }

    getCurrentUserSession(new SessionListener() {
        @Override
        public void onSuccess() {
            executeApiCall(request, taskListener);
        }

        @Override
        public void onFailure(ApiError error) {
            if (taskListener != null)
                taskListener.onError(error);
        }
    });

}

private <T> void executeApiCall(Single<T> request, ApiTaskListener<T> taskListener) {
    getCompositeDisposable().add(request
            .subscribeOn(getSchedulerProvider().io())
            .observeOn(getSchedulerProvider().ui())
            .subscribe((Consumer<T>) response -> {
                if (taskListener != null)
                    taskListener.onResponse(response);
            }, throwable -> {
                if (taskListener != null)
                    taskListener.onError(AppApiHelper.parseApiError(throwable));
            }));
}


public interface ApiTaskListener<T>{
    void onResponse(T response);

    void onError(ApiError apiError);
}

Хотя я бы порекомендовал вам переделать все текущие обратные вызовы (ApiTaskListener можно удалить и изменить/ перегрузить getCurrentUserSession как блокирующий вызов), тогда вы можете просто вернуть Single<T> и подписаться на него, а не заключать его в обратный вызов.Я не знаю достаточно о другом коде, чтобы действительно обеспечить достойную основу для этого.

...