内存泄漏使用Lollipop的过渡

时间:2016-03-04 08:58:20

标签: android memory-leaks android-transitions

我正在尝试使用RecyclerView和DetailActivity实现fragment(连接到MainActivity)之间的转换。

在我的片段中,我在 onStart()方法中添加了RecyclerView监听器:

@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();
    }

您可以看到转换从if块开始。在DetailActivity中,我有以下方法,我在 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);
        }
    }

在MainActivity中我有几乎类似的方法,我也在 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);
        }
    }

我还在DetailActivity中实现了 Transition.TransitionListener 接口,因为文档说: 转换侦听器接收来自转换的通知。通知表示转换生命周期事件。

所以我试图删除 onTransitionEnd(Transition transition),onTransitionCancel(Transition transition) onTransitionPause(Transition transition)回调中的侦听器:

    @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) {

    }

我正在使用LeakCanary进行内存泄漏检测,并在转换后检测到内存泄漏:

enter image description here enter image description here

所以我想知道如何删除转换侦听器以防止此内存泄漏?

2 个答案:

答案 0 :(得分:0)

确保您释放Activity引用,因为您在Transition类中坚持它。在它的Transition.removeListener(this)方法中,一个简单的onDestroy()(因为你的活动实现了接口)应该可以防止内存泄漏。

答案 1 :(得分:0)

感谢Albert Vila answer。根据{{​​3}}主题,问题在于TransitionManager.sRunningTransitions