2

I'm trying to implement transition between fragment (that attached to the MainActivity) with RecyclerView and the DetailActivity.

In my fragment, I've added RecyclerView listener in onStart() method:

@Override
public void onStart() {
        super.onStart();
        mRecyclerItemClickListener = new RecyclerItemClickListener(getActivity(), (view, position) -> {
            Intent intent = new Intent(getActivity(), DetailActivity.class);
            intent.putExtra(ConstantsManager.POSITION_ID_KEY, mFilmsAdapter.getImdbIdByPosition(position));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                ActivityOptionsCompat optionsCompat = ActivityOptionsCompat
                        .makeSceneTransitionAnimation(getActivity());
                ActivityCompat.startActivity(getActivity(), intent, optionsCompat.toBundle());
            } else {
                startActivity(intent);
            }
        });
        mRecyclerView.addOnItemTouchListener(mRecyclerItemClickListener);
        mSwipeRefreshLayout.setOnRefreshListener(this);
        mTopFilmsPresenter.attachView(this);
        mTopFilmsPresenter.getFilms();
    }

You can see, that the transition begins in the if block. In the DetailActivity I have the following method which I call in onCreate():

@TargetApi(Build.VERSION_CODES.KITKAT)
private void setupWindowAnimations() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Explode explode = new Explode();
            explode.setDuration(ConstantsManager.TRANSITION_DURATION);
            getWindow().setEnterTransition(explode);
            getWindow().setExitTransition(explode);
        }
    }

And in the MainActivity I have almost a similar method, which I also call in onCreate():

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void setWindowAnimations() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Explode explode = new Explode();
            explode.setDuration(ConstantsManager.TRANSITION_DURATION);
            getWindow().setEnterTransition(explode);
            getWindow().setExitTransition(explode);
            getWindow().setReenterTransition(explode);
            getWindow().setReturnTransition(explode);
        }
    }

I've also implemented Transition.TransitionListener interface in the DetailActivity, because documentation says: A transition listener receives notifications from a transition. Notifications indicate transition lifecycle events.

So I'm trying to remove listener in the onTransitionEnd(Transition transition), onTransitionCancel(Transition transition) and onTransitionPause(Transition transition) callbacks:

    @Override
    public void onTransitionStart(Transition transition) {

    }

    @TargetApi(Build.VERSION_CODES.KITKAT)
    @Override
    public void onTransitionEnd(Transition transition) {
        transition.removeListener(this);
    }

    @TargetApi(Build.VERSION_CODES.KITKAT)
    @Override
    public void onTransitionCancel(Transition transition) {
        transition.removeListener(this);
    }

    @TargetApi(Build.VERSION_CODES.KITKAT)
    @Override
    public void onTransitionPause(Transition transition) {
        transition.removeListener(this);
    }

    @Override
    public void onTransitionResume(Transition transition) {

    }

I'm using LeakCanary for memory leaks detections and it detects a memory leak after transition:

enter image description here enter image description here

So I am wondering how can I remove transition listener(s) to prevent this memory leak?

c0nst
  • 735
  • 11
  • 25
  • 2
    I have the exact same problem (detected with LeakCanary also). Take a look at [this answer](http://stackoverflow.com/a/34542473/4034572) from a question that's exactly the same issue. It works for me. – Albert Vila Calvo Mar 28 '16 at 19:15
  • @AlbertVila sorry for the long respond. You're absolutely right. Thanks for the answer! – c0nst Apr 13 '16 at 09:42
  • Possible duplicate of [SharedElement and custom EnterTransition causes memory leak](http://stackoverflow.com/questions/32698049/sharedelement-and-custom-entertransition-causes-memory-leak) – Richard Le Mesurier Jan 20 '17 at 08:10

2 Answers2

0

Ensure that you release the Activity reference since you are strongly holding onto it within the Transition class. A simple Transition.removeListener(this) (since your activity implements the interface) in it's onDestroy() method should prevent memory leaks.

Andrew Grosner
  • 2,337
  • 2
  • 18
  • 14
0

Thanks Albert Vila for the answer. The problem lies in TransitionManager.sRunningTransitions according to this topic.

Community
  • 1
  • 1
c0nst
  • 735
  • 11
  • 25