Ошибка при получении ответа от сервера

У меня проблемы с ott+activity+fragment.1. Я открываю Активность и регистрирую Отто в onCreate.

Observer.getInstance().register(this);

2. Я отправляю запрос на сервер, если мой метод завершен

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

3. Ждите в этом методе

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

4. Мой фрагмент

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

с первого раза все отлично работает. Затем я закрываю Activity. открывается снова. и ошибка

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)

1 ответ

Я предлагаю вам зарегистрироваться и отменить регистрацию отто в onResume а также onPause, Если я правильно понял, ваш код работает так:

  1. Вы регистрируете обработчик событий в onCreate,
  2. Что-то происходит, это работает нормально.
  3. Приложение переходит в фоновый режим, как правило, это нормально, если Activity Объект уничтожается и собирается как мусор, НО Отто хранит свою ссылку, поэтому gc не может его собрать.
  4. Приложение открывается снова, другое Activity объект создан и зарегистрирован
  5. Что-то запускает событие, и Отто передает его старому действию, которое должно было быть уничтожено, но все еще живо, потому что Отто сохраняет свою ссылку. Приложение аварийно завершает работу, потому что это действие находится в конце своего жизненного цикла.

Подводя итог: рекомендуется не хранить ссылки на объекты, которые могут быть уничтожены в любое время, поэтому в этом случае вам следует отменить регистрацию. Activity когда приложение переходит в фоновый режим.

Другие вопросы по тегам