sockeqwe / mosby

A Model-View-Presenter / Model-View-Intent library for modern Android apps
http://hannesdorfmann.com/mosby/
Apache License 2.0
5.49k stars 841 forks source link

ClassCastException in MvpNullObjectBasePresenter #194

Closed manabreak closed 7 years ago

manabreak commented 7 years ago

I ran into this problem when using MvpNullObjectBasePresenter. When a fragment is destroyed, the following error crashes the application:

java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
    at com.hannesdorfmann.mosby.mvp.MvpNullObjectBasePresenter.detachView(MvpNullObjectBasePresenter.java:38)

Took a quick glance at the source, but didn't see a solution right away. I thought it was because my views used two generic types for the presenter (P extends MvpPresenter<V> & Refreshable), but after taking the other type out, the problem persists.

The problem happens when this fragment gets destroyed:

public class InboxFragment extends MessageBaseFragment<InboxPresenter> {
    @NonNull
    @Override
    public InboxPresenter createPresenter() {
        return new InboxPresenter(...);
    }
}

MessageBaseFragment looks like this (unrelevant code omitted):

public abstract class MessageBaseFragment<P extends BaseMessagePresenter> extends BaseMvpFragment<MessageView, P> implements MessageView {
    ...
}

And the BaseMvpFragment is just a small container for injected dependencies:

public abstract class BaseMvpFragment<V extends MvpView, P extends MvpPresenter<V>> extends MvpFragment<V, P> {
    ...
}

Okay, moving on, the InboxPresenter:

public class InboxPresenter extends BaseMessagePresenter {
    ...
}

And BaseMessagePresenter:

public abstract class BaseMessagePresenter extends MvpNullObjectBasePresenter<MessageView> {
    ...
}

Finally, MessageView:

public interface MessageView extends MvpView {
    ...
}
sockeqwe commented 7 years ago

Which version of Mosby are you using?

manabreak notifications@github.com schrieb am Sa., 21. Jan. 2017, 12:09:

I ran into this problem when using MvpNullObjectBasePresenter. When a fragment is destroyed, the following error crashes the application:

java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType at com.hannesdorfmann.mosby.mvp.MvpNullObjectBasePresenter.detachView(MvpNullObjectBasePresenter.java:38)

Took a quick glance at the source, but didn't see a solution right away. I thought it was because my views used two generic types for the presenter (P extends MvpPresenter & Refreshable), but after taking the other type out, the problem persists.

The problem happens when this fragment gets destroyed:

public class InboxFragment extends MessageBaseFragment { @NonNull @Override public InboxPresenter createPresenter() { return new InboxPresenter(...); } }

MessageBaseFragment looks like this (unrelevant code omitted):

public abstract class MessageBaseFragment

extends BaseMvpFragment<MessageView, P> implements MessageView { ... }

And the BaseMvpFragment is just a small container for injected dependencies:

public abstract class BaseMvpFragment<V extends MvpView, P extends MvpPresenter> extends MvpFragment<V, P> { ... }

Okay, moving on, the InboxPresenter:

public class InboxPresenter extends BaseMessagePresenter { ... }

And BaseMessagePresenter:

public abstract class BaseMessagePresenter extends MvpNullObjectBasePresenter { ... }

Finally, MessageView:

public interface MessageView extends MvpView { ... }

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/sockeqwe/mosby/issues/194, or mute the thread https://github.com/notifications/unsubscribe-auth/AAjnrpN6FsubxJkQ-4d6O0sMyPwIV6BFks5rUedjgaJpZM4LqCdq .

manabreak commented 7 years ago

I'm using 2.0.1.

sockeqwe commented 7 years ago

This should be fixed with 3.0.0 snapshot. Can you try if this is fixed with 3.0 snapshot?

manabreak notifications@github.com schrieb am Sa., 21. Jan. 2017, 12:45:

I'm using 2.0.1.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/sockeqwe/mosby/issues/194#issuecomment-274256810, or mute the thread https://github.com/notifications/unsubscribe-auth/AAjnrqoEeQsXMUDPG2M6pDDzPp09zZcSks5rUe_rgaJpZM4LqCdq .

manabreak commented 7 years ago

Hmm, Gradle seems to be having problems resolving compile 'com.hannesdorfmann.mosby3:mvp:3.0.0-SNAPSHOT'. Is there something that should be changed in addition?

sockeqwe commented 7 years ago

You also have to add the url to the snapshot repository:

allprojects {
  repositories {
    ...

    maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}
sockeqwe commented 7 years ago

And the package name of all classes has been changed from com.hannesdorfmann.mosby to com.hannesdorfmann.mosby3

Simply do a search and replace in Android Studio to change the package name in your classes import statements.

manabreak commented 7 years ago

The issue seems to be solved when using 3.0.0 snapshot. Thanks!

cyberrob-zz commented 7 years ago

Comparing com.hannesdorfmann.mosby.mvp.MvpNullObjectBasePresenter & com.hannesdorfmann.mosby3.mvp.MvpNullObjectBasePresenter, it seems that constructor in the newer version did some magics to recursively check if subclasses is some kind of class in isSubTypeOfMvpView() method.

It's awesome! Thanks!