0

I am have problem with ott+activity+fragment. 1. I am open Activity and register otto in onCreate.

Observer.getInstance().register(this);

2. I am send request to the server if my method finished

@Override
    public void didScanBarcode(String barcode, String symbology) {
      ...
        ItemApiConnector.me().getItem(cleanedBarcode);
    }

3. Wait in this method

@Subscribe(MessageType.ITEM_SUCCESS)
    public void getItemFromServer(Item item) {
        Fragment fragment =  ItemFragment.newInstance(item);
        setFragment(fragment);
}

4. My Fragment

public class ItemFragment extends Fragment {
    private Item item;
    private TextView tvName;
    private TextView tvPrice;
    private ImageView itemImage;
    private DisplayImageOptions options;
    AnimateFirstDisplayListener animateFirstDisplayListener = new AnimateFirstDisplayListener();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.item_info, container, false);
        Bundle bundle = getArguments();
        item  = (Item) bundle.getSerializable("item");
        tvName = (TextView) rootView.findViewById(R.id.tvItemName);
        tvPrice = (TextView) rootView.findViewById(R.id.tvPrice);
        itemImage = (ImageView) rootView.findViewById(R.id.itemImage);
        tvName.setText(item.getName());
        tvPrice.setText("$"+item.getPrice());
        options = ILOptions.getOption();
        ImageLoader.getInstance().displayImage(item.getImage(), itemImage, options,         animateFirstDisplayListener);
        return rootView;
    }

    public static ItemFragment newInstance(Item item) {
        ItemFragment f = new ItemFragment();
        Bundle b = new Bundle();
        b.putSerializable("item", item);
        f.setArguments(b);
        return f;
    }
}

first time everything works fine. Then I close Activity. opens again. and an error

java.lang.RuntimeException: Could not dispatch event: class com.skip.client.models.Item to handler [EventHandler public void com.skip.client.customer.activities.ScanActivity.getItemFromServer(com.skip.client.models.Item)]: Can not perform this action after onSaveInstanceState
            at com.skip.client.core.otto.Bus.throwRuntimeException(Bus.java:458)
            at com.skip.client.core.otto.Bus.dispatch(Bus.java:388)
            at com.skip.client.core.otto.Bus.dispatchQueuedEvents(Bus.java:369)
            at com.skip.client.core.otto.SkipBus.post(SkipBus.java:52)
            at com.skip.client.core.Observer.send(Observer.java:26)
            at com.skip.client.connector.DefaultCallback.onSuccess(DefaultCallback.java:134)
            at com.skip.client.connector.DefaultCallback.success(DefaultCallback.java:55)
            at com.skip.client.connector.DefaultCallback.success(DefaultCallback.java:23)
            at retrofit.CallbackRunnable$1.run(CallbackRunnable.java:45)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:149)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
            at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1365)
            at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1383)
            at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:636)
            at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:615)
            at com.skip.client.customer.activities.ScanActivity.setFragment(ScanActivity.java:128)
            at com.skip.client.customer.activities.ScanActivity.getItemFromServer(ScanActivity.java:135)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.skip.client.core.otto.EventHandler.handleEvent(EventHandler.java:89)
            at com.skip.client.core.otto.Bus.dispatch(Bus.java:386)
            at com.skip.client.core.otto.Bus.dispatchQueuedEvents(Bus.java:369)
            at com.skip.client.core.otto.SkipBus.post(SkipBus.java:52)
            at com.skip.client.core.Observer.send(Observer.java:26)
            at com.skip.client.connector.DefaultCallback.onSuccess(DefaultCallback.java:134)
            at com.skip.client.connector.DefaultCallback.success(DefaultCallback.java:55)
            at com.skip.client.connector.DefaultCallback.success(DefaultCallback.java:23)
            at retrofit.CallbackRunnable$1.run(CallbackRunnable.java:45)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:149)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
            at dalvik.system.NativeStart.main(Native Method)
Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
Pavel Petrashov
  • 257
  • 1
  • 4
  • 13

1 Answers1

3

I suggest you to register and unregister otto in onResume and onPause. If i got it right your code works like this:

  1. You register event handler in onCreate.
  2. Something happens it works ok.
  3. App goes to background, generally it's ok if Activity object is destroed and collected as garbage BUT otto holds its reference so gc cannot collect it.
  4. The app is opened again, another Activity object is created and registered
  5. Something fires an event and otto delivers it to an old activity which should have been destroyed but still alive because otto holds its reference. App crashes with exception, because that activity is in the end of its lifecycle.

To sum up: it's a good practice not to hold references to objects that can be destroyed at any time, so in this case you should unregister Activity when app goes to background.

MightySeal
  • 2,293
  • 2
  • 17
  • 32