Android – greenroot’s eventbus: two fragments call asynchronous tasks to work, which puzzles eventbus

I am currently dealing with fragments created under activities using the fragmentpageradapter. I use eventbus 3.0 of greenrobot to return some asynctasks I created from the service class. However, since these two fragments are created one by one, the return of event bus' post sticky 'makes the subscribed fragments mixed. I have searched stackoverflow, After doing what others have done (such as putting the eventbus register into OnStart and onstop, etc.), I still can't see similar problems. I hope you can help me. Thank you!

These are my two fragments: (I omitted some unnecessary code)

1. Status fragment

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    Log.e(TAG, "StatusFragment onCreateView");
    eventBus = EventBus.getDefault();
    eventBus.register(this);
    StatusService statusService = StatusService.newInstance(getContext());
    statusService.getStatusList(); //Async Task to call onReturnAdapter once finished
    return mRecyclerView;
}

@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onReturnList(List<Status> statuses) {
    Log.e(TAG, "onReturnList");
    mAdapter = new StatusRecyclerAdapter(statuses);
    mRecyclerView.setAdapter(mAdapter);
    eventBus.removeStickyEvent(statuses);
}

@Override
public void onStop() {
    Log.e(TAG, "onStop");
    eventBus.unregister(this);
    super.onStop();
}

2. Status Service - the service class of the status fragment

public void getStatusList () {
    Log.e(LOG_TAG, "getStatusList");
    //do some async tasks here
    returnList(statuses);

}

private void returnList(List<Status> statuses) {
    Log.e(LOG_TAG, "returnList");
    eventBus.postSticky(statuses);
}

3. Chart fragments

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    Log.e(LOG_TAG, "onCreateView");

    eventBus = EventBus.getDefault();
    eventBus.register(this);

    chartService = ChartService.newInstance(getContext());
    chartService.getDateResult(new DbRequestFeelings());
    return view;
}

@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onReturnResults(List<Result> results) {
    Log.e(LOG_TAG, "onReturnResults");

    chartService.setupPieChart(results, feelingsPieChart);
}

@Override
public void onStop() {
    eventBus.unregister(this);
    super.onStop();
}

4. Chart Service

public void getDateResult(final DbRequest dbRequest) {
    Log.e(LOG_TAG, "getDateResult");
    //do some async tasks
    returnResults(results);
}

private void returnResults(List<Result> results) {
    Log.e(LOG_TAG, "returnResults");
    eventBus.postSticky(results);
}

5. Results

public class Result {
      ....
}

6. Status class

public class Status {
    ...
}

Therefore, each time a fragment is created, they will call their service class, and the service class will publish list < status > and list < result > almost one by one. For this reason, it causes confusion

03-11 11:48:19.685  15148-15148/com.paularagones.moode E/EventBus﹕ Could not dispatch event: class java.util.ArrayList to subscribing class class com.paularagones.moode.Fragments.ChartFragment
    java.lang.ClassCastException: com.paularagones.moode.Models.Status cannot be cast to com.paularagones.moode.Models.Result

This is the complete stack trace:

03-11 11:48:19.589  15148-15148/com.paularagones.moode E/Moode-StatusFragment﹕ StatusFragment onCreate
03-11 11:48:19.589  15148-15148/com.paularagones.moode E/Moode-StatusFragment﹕ StatusFragment onCreateView
03-11 11:48:19.605  15148-15148/com.paularagones.moode E/StatusService﹕ getStatusList
03-11 11:48:19.609  15148-15148/com.paularagones.moode E/ChartFragment﹕ onCreateView
03-11 11:48:19.613  15148-15148/com.paularagones.moode E/ChartService﹕ newInstance
03-11 11:48:19.621  15148-15148/com.paularagones.moode E/ChartService﹕ getDateResult
03-11 11:48:19.681  15148-15148/com.paularagones.moode E/RecyclerView﹕ No adapter attached; skipping layout
03-11 11:48:19.681  15148-15148/com.paularagones.moode E/StatusService﹕ returnList
03-11 11:48:19.681  15148-15148/com.paularagones.moode E/Moode-StatusFragment﹕ onReturnList
03-11 11:48:19.681  15148-15148/com.paularagones.moode E/ChartFragment﹕ onReturnResults
03-11 11:48:19.685  15148-15148/com.paularagones.moode E/EventBus﹕ Could not dispatch event: class java.util.ArrayList to subscribing class class com.paularagones.moode.Fragments.ChartFragment
    java.lang.ClassCastException: com.paularagones.moode.Models.Status cannot be cast to com.paularagones.moode.Models.Result
            at com.paularagones.moode.Services.ChartService.getData(ChartService.java:147)
            at com.paularagones.moode.Services.ChartService.setupPieChart(ChartService.java:129)
            at com.paularagones.moode.Fragments.ChartFragment.onReturnResults(ChartFragment.java:116)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at org.greenrobot.eventbus.EventBus.invokeSubscriber(EventBus.java:485)
            at org.greenrobot.eventbus.EventBus.postToSubscription(EventBus.java:420)
            at org.greenrobot.eventbus.EventBus.postSingleEventForEventType(EventBus.java:397)
            at org.greenrobot.eventbus.EventBus.postSingleEvent(EventBus.java:370)
            at org.greenrobot.eventbus.EventBus.post(EventBus.java:251)
            at org.greenrobot.eventbus.EventBus.postSticky(EventBus.java:292)
            at com.paularagones.moode.Services.StatusService.returnList(StatusService.java:80)
            at com.paularagones.moode.Services.StatusService.access$100(StatusService.java:24)
            at com.paularagones.moode.Services.StatusService$2.onNext(StatusService.java:72)
            at com.paularagones.moode.Services.StatusService$2.onNext(StatusService.java:59)
            at rx.Observable$30.onNext(Observable.java:8069)
            at rx.observers.SafeSubscriber.onNext(SafeSubscriber.java:139)
            at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:202)
            at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:162)
            at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
            at android.os.Handler.handleCallback(Handler.java:615)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4745)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)
03-11 11:48:19.685  15148-15148/com.paularagones.moode E/ChartService﹕ returnResults
03-11 11:48:19.685  15148-15148/com.paularagones.moode E/Moode-StatusFragment﹕ onReturnList
03-11 11:48:19.685  15148-15148/com.paularagones.moode E/ChartFragment﹕ onReturnResults
03-11 11:48:19.693  15148-15148/com.paularagones.moode E/StatusRecyclerAdapter﹕ onCreateViewHolder
03-11 11:48:19.697  15148-15148/com.paularagones.moode E/StatusRecyclerAdapter﹕ onBindViewHolder
03-11 11:48:19.709  15148-15148/com.paularagones.moode E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.ClassCastException: com.paularagones.moode.Models.Result cannot be cast to com.paularagones.moode.Models.Status
            at com.paularagones.moode.Adapters.StatusRecyclerAdapter.onBindViewHolder(StatusRecyclerAdapter.java:101)
            at com.paularagones.moode.Adapters.StatusRecyclerAdapter.onBindViewHolder(StatusRecyclerAdapter.java:28)
            at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5277)
            at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5310)
            at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4568)
            at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4461)
            at android.support.v7.widget.linearlayoutmanager$LayoutState.next(linearlayoutmanager.java:1962)
            at android.support.v7.widget.linearlayoutmanager.layoutChunk(linearlayoutmanager.java:1371)
            at android.support.v7.widget.linearlayoutmanager.fill(linearlayoutmanager.java:1334)
            at android.support.v7.widget.linearlayoutmanager.onLayoutChildren(linearlayoutmanager.java:563)
            at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2847)
            at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3145)
            at android.view.View.layout(View.java:13754)
            at android.view.ViewGroup.layout(ViewGroup.java:4362)
            at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1627)
            at android.view.View.layout(View.java:13754)
            at android.view.ViewGroup.layout(ViewGroup.java:4362)
            at android.support.design.widget.CoordinatorLayout.layoutChild(CoordinatorLayout.java:1034)
            at android.support.design.widget.CoordinatorLayout.onLayoutChild(CoordinatorLayout.java:744)
            at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
            at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1180)
            at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:757)
            at android.view.View.layout(View.java:13754)
            at android.view.ViewGroup.layout(ViewGroup.java:4362)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:13754)
            at android.view.ViewGroup.layout(ViewGroup.java:4362)
            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1649)
            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1507)
            at android.widget.LinearLayout.onLayout(LinearLayout.java:1420)
            at android.view.View.layout(View.java:13754)
            at android.view.ViewGroup.layout(ViewGroup.java:4362)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:13754)
            at android.view.ViewGroup.layout(ViewGroup.java:4362)
            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1649)
            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1507)
            at android.widget.LinearLayout.onLayout(LinearLayout.java:1420)
            at android.view.View.layout(View.java:13754)
            at android.view.ViewGroup.layout(ViewGroup.java:4362)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)
            at android.view.View.layout(View.java:13754)
            at android.view.ViewGroup.layout(ViewGroup.java:4362)
            at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1866)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1687)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:998)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4212)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
            at android.view.Choreographer.doCallbacks(Choreographer.java:555)
            at android.view.Choreographer.doFrame(Choreographer.java:525)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
            at android.os.Handler.handleCallback(Handler.java:615)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4745)
            at java.lang.reflect.Method.invokeNative(Native Method)

Do you know what's wrong with my code? thank you.

resolvent:

The first thing I noticed is that you didn't remove the stickiness in the onreturnresults (list < result > results) method... I'm not sure if it's intentional... But I think it should be mentioned

The main point I want to emphasize is that there are two onevent () methods that use the same common class list < > – this may be a problem – a small code change and quick test can verify this

Create a class for each list < >

public class Statuses
{
    List<Status> list;
    public Statuses(List<Status> data) { list = data; }
}

public class Results
{
    List<Result> list;
    public Results(List<Result> data) { list = data; }
}

Update onevent() method signature:

public void onReturnList(Statuses statuses)
public void onReturnResults(Results results)

Update. Poststicky() method call:

eventBus.postSticky(new Statuses(statuses));
eventBus.postSticky(new Results(results));

Of course, you need to access the list from its class members (for example):

foreach (var status in statuses.list)

and

foreach (var result in results.list)

If the problem you see disappears after these changes - it makes sense to assume that the eventbus of greenrobot does not consider the types contained in the generic list class during the reflection call seen in callstack. It may just look for the first matching signature containing the list parameter; When there are 2 or more matches, the correct match may not be called

This is speculation; So you have to try to see if it helps - but when I need the list < > class to avoid ambiguity, I have successfully used the eventbus of greenrobot in projects using this type of implementation

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>