简体   繁体   中英

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

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 {}

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'.

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() {}

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM