Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix:issues 539 #615

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Conversation

o0starshine0o
Copy link

@o0starshine0o o0starshine0o commented Nov 7, 2019

refer:refer
issue: issue

@o0starshine0o
Copy link
Author

@greenrobot @greenrobot-team
Please check this request,thanks

}
// Put any non-Method object to "consume" the existing Method
anyMethodByEventType.put(eventType, this);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please explain how this change affects which subscriber method is detected? Won't that break existing code?

The code comment indicates that the put call should have been outside the if condition all along.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When duplicate register subscribe method, the method didn't wrap by FindState, so the next checkAddWithMethodSignature return false.

Here is an example:

we prepare 2 classes

open class EventBusBaseFragment : Fragment() {
    @Subscribe
    open fun subscribeMessage0(message: SendMessage) {
        Log.d("EventBusBaseFragment", "EventBusBaseFragment subscribeMessage0")
    }

    @Subscribe
    open fun subscribeMessage1(message: SendMessage) {
        Log.d("EventBusBaseFragment", "EventBusBaseFragment subscribeMessage1")
    }
}
open class SendFragment : EventBusBaseFragment() {
    @Subscribe
    override fun subscribeMessage0(message: SendMessage) {
        Log.d("SendFragment", "SendFragment subscribeMessage0")
    }

    @Subscribe
    override fun subscribeMessage1(message: SendMessage) {
        Log.d("SendFragment", "SendFragment subscribeMessage1")
    }
}

Also the key code

// /org/greenrobot/eventbus/SubscriberMethodFinder.java
boolean checkAdd(Method method, Class<?> eventType) {
    Object existing = anyMethodByEventType.put(eventType, method);
    if (existing == null) {
        return true;
    } else {
        if (existing instanceof Method) {
            if (!checkAddWithMethodSignature((Method) existing, eventType)) {
                throw new IllegalStateException();
            }
            anyMethodByEventType.put(eventType, this);
        }
        return checkAddWithMethodSignature(method, eventType);
    }
}
// /org/greenrobot/eventbus/SubscriberMethodFinder.java
private boolean checkAddWithMethodSignature(Method method, Class<?> eventType) {
    methodKeyBuilder.setLength(0);
    methodKeyBuilder.append(method.getName());
    methodKeyBuilder.append('>').append(eventType.getName());

    String methodKey = methodKeyBuilder.toString();
    Class<?> methodClass = method.getDeclaringClass();
    Class<?> methodClassOld = subscriberClassByMethodKey.put(methodKey, methodClass);
        if (methodClassOld == null || methodClassOld.isAssignableFrom(methodClass)) {
            return true;
        } else {
            subscriberClassByMethodKey.put(methodKey, methodClassOld);
            return false;
        }
    }
}

here is an analysis:

  1. first register : SendFragment#subscribeMessage0
    the key var in checkAddWithMethodSignature function is
methodClass:com.abelhu.androidstudy.ui.send.SendFragment
methodClassOld:null
methodKey:subscribeMessage0>com.abelhu.androidstudy.message.SendMessage

method insert into anyMethodByEventType directly

  1. second register: SendFragment#subscribeMessage1
    the key var in checkAddWithMethodSignature function is
methodClass:com.abelhu.androidstudy.ui.send.SendFragment
methodClassOld:null
methodKey:subscribeMessage1>com.abelhu.androidstudy.message.SendMessage

because the methodKey is different from first insert, so wrap method as FindState insert into anyMethodByEventType
2. third register : EventBusBaseFragment#subscribeMessage0
the key var in checkAddWithMethodSignature function is

methodClass:com.abelhu.androidstudy.ui.send.EventBusBaseFragment
methodClassOld:com.abelhu.androidstudy.ui.send.SendFragment
methodKey:subscribeMessage0>com.abelhu.androidstudy.message.SendMessage

method was inserted into anyMethodByEventType,
but in line 13 : **method not warp as FindState **, it was inserted directly!!!
3. fourth register: EventBusBaseFragment#subscribeMessage1
the key var in checkAddWithMethodSignature function is

methodClass:com.abelhu.androidstudy.ui.send.EventBusBaseFragment
methodClassOld:com.abelhu.androidstudy.ui.send.SendFragment
methodKey:subscribeMessage0>com.abelhu.androidstudy.message.SendMessage

eventType is equal, we get the third method, not FindState
when check by checkAddWithMethodSignature, it return false, so it throw an exception.


What we do

What we do is moving the code to wrap all method as FindState, so the check can pass.
Here is a detail analysis in chinese, refer

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@greenrobot-team
I don't know whether I express my meaning clearly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants