How to fix "unchecked call to 'attachView(V)' as a member of raw type 'BasePresenter'"?

Question

I have already looked up many answers here about this issue but for the life of me I can't seem to fix this problem on my end and I need some help.

BasePresenter:

public abstract class BasePresenter<V> {

    private V mView;

    public void attachView(V view) { mView = view; }
    public void detachView() { mView = null; }

}

BaseFragment:

public abstract class BaseFragment<P extends BasePresenter> extends Fragment {

    @Inject protected P mPresenter;

    @Override
    public void onResume() {
        super.onResume();
        mPresenter.attachView(this); // unchecked call to 'attachView(V)' as a member of raw type 'BasePresenter'
    }

    @Override
    public void onPause() {
        super.onPause();
        mPresenter.detachView();
    }

}

MyPresenter:

public class MyPresenter extends BasePresenter<MyPresenter.MyView> {

    @Inject
    public MyPresenter() {}

    public interface MyView {}

}

MyFragment:

public class MyFragment extends BaseFragment implements MyPresenter.MyView {}

Show source
| generics   | java   | android   | mvp   | dagger-2   2017-01-05 13:01 2 Answers

Answers ( 2 )

  1. 2017-01-05 15:01

    The problem is in the type-variable declaration:

    class BaseFragment<P extends BasePresenter>
    

    BasePresenter is a generic class, so you need to specify what its type parameter is. From this snippet:

    mPresenter.attachView(this);
    

    It would seem that you expect BaseFragment to be bound to the type-variable V in BasePresenter - so I would rewrite your BaseFragment declaration as follows:

    abstract class BaseFragment<P extends BasePresenter<BaseFragment<P>>> { ... }
    

    That should take care of the unchecked warning. That said, I strongly suspect that what you are really after is something like this:

    abstract class BaseFragment<P extends BasePresenter<V>, V> { ... }
    

    Where V is an independent type-variable modelling the 'view'.

  2. 2017-01-05 22:01

    Simple, instead of

    public abstract class BaseFragment<P extends BasePresenter> extends Fragment {
    

    It should be

    public abstract class BaseFragment<V, P extends BasePresenter<V>> extends Fragment { 
    

    or

    public abstract class BaseFragment<P extends BasePresenter<BaseFragment<P>>> extends Fragment { 
    

    or

    public abstract class BaseFragment<V extends BaseFragment<V, P>, P extends BasePresenter<V>> extends Fragment { 
    

    Basically, make sure the BasePresenter is parametrized with something.




    EDIT:

    Okay, based on what you're actually trying to do, you should do it like this:

    public abstract class BasePresenter<V> {
    
        private V mView;
    
        public void attachView(V view) { mView = view; }
        public void detachView() { mView = null; }
    }
    
    public abstract class BaseFragment<V extends BaseFragment<V, P>, P extends BasePresenter<V>> extends Fragment {
    
        protected abstract P getPresenter();
    
        @Override
        public void onResume() {
            super.onResume();
            getPresenter().attachView(this); // unchecked call to 'attachView(V)' as a member of raw type 'BasePresenter'
        }
    
        @Override
        public void onPause() {
            super.onPause();
            getPresenter().detachView();
        }
    }
    
    public class MyPresenter extends BasePresenter<MyPresenter.MyView> {
        @Inject
        public MyPresenter() {}
    
        public interface MyView {}
    }
    
    public class MyFragment extends BaseFragment<MyFragment, MyPresenter> implements MyPresenter.MyView {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            MyFragmentComponent component = ((MainActivity)getActivity()).getComponent().myFragmentComponent();
            component.inject(this);
            View view = inflater.inflate(R.layout.blah, container, false);
            ButterKnife.bind(this, view);
            return view;
        }
    }
    



    EDIT2: Based on provided example:

    public class RexTester {
        // MAIN CLASS
    
        static class Rextester {
            public static void main(String args[]) {
                new MyFragment();
            }
        }
    
    // MVP CODE
    
        interface BaseView {}
    
        final static class MyPresenter extends BasePresenter<MyPresenter.MyView> {
    
            public MyPresenter() {}
    
            public void executeAction() {
                mView.onCallback();
            }
    
            interface MyView extends BaseView {
                void onCallback();
            }
    
        }
    
        abstract static class BasePresenter<V extends BaseView> {
    
            protected V mView;
    
            public void attachView(V view) { mView = view;}
            public void detachView() { mView = null; }
    
        }
    
        final static class MyFragment extends BaseFragment<MyPresenter.MyView, MyPresenter> implements MyPresenter.MyView {
    
            private MyPresenter mPresenter;
    
            public MyFragment() {
                mPresenter = new MyPresenter();
    
                onResume(); // Mock onResume() lifecycle event!
    
                mPresenter.executeAction();
    
                onPause(); // Mock onPause() lifecycle event!
            }
    
            protected MyPresenter getPresenter() {
                return mPresenter;
            }
    
            @Override
            protected MyPresenter.MyView getThis() {
                return this;
            }
    
            public void onCallback() {
                System.out.println("Hello AndroidMVP!");
            }
        }
    
        abstract static class BaseFragment<V extends BaseView, P extends BasePresenter<V>> extends Fragment implements BaseView {
    
            protected abstract P getPresenter();
    
            protected void onResume() {
                super.onResume();
                getPresenter().attachView(getThis());
            }
    
            protected abstract V getThis();
    
            protected void onPause() {
                super.onPause();
                getPresenter().detachView();
            }
        }
    
    // ANDROID FRAMEWORK MOCK
    
        abstract static class Fragment {
    
            protected void onResume() {}
    
            protected void onPause() {}
    
        }
    }
    
◀ Go back