知道可能是什么原因?
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:* com.feeln.android.activity.MovieDetailActivity已泄露:
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:* GC ROOT android.app.ActivityThread $ApplicationThread.this $0
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*引用android.app.ActivityThread.mActivities
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*引用android.util.ArrayMap.mArray
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*引用数组java.lang.Object [].[1]
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*引用android.app.ActivityThread $ActivityClientRecord.activity
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*引用com.feeln.android.activity.MovieDetailActivity.mActivityTransitionState
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*引用android.app.ActivityTransitionState.mEnterTransitionCoordinator
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*引用android.app.EnterTransitionCoordinator.mEnterViewsTransition
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*引用android.transition.TransitionSet.mParent
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*引用android.transition.TransitionSet.mListeners
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*引用java.util.ArrayList.array
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*引用数组java.lang.Object [].[1]
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*引用android.transition.TransitionManager $MultiListener $1.val $runningTransitions(匿名类扩展android.transition.Transition $TransitionListenerAdapter)
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*引用android.util.ArrayMap.mArray
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*引用数组java.lang.Object [].[2]
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*引用com.android.internal.policy.impl.PhoneWindow $DecorView.mContext
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*泄漏com.feeln.android.activity.MovieDetailActivity实例
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:[09-21 16:19:31.007 28269:31066 D / LeakCanary]
*参考密钥:af2b6234-297e-4bab-96e9-02f1c4bca171
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*设备:LGE google Nexus 5 hammerhead
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:* Android版本:5.1.1 API:22 LeakCanary:1.3.1
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:*持续时间:watch = 6785ms,gc = 262ms,堆转储= 8553ms,分析= 33741ms
09-21 16:19:31.007 28269-31066 / com.sample.android D / LeakCanary:[09-21 16:19:31.007 28269:31066 D / LeakCanary]
要重现,您需要拥有一个大的共享图像动画,还需要一个自定义的EnterAnimation和setEnterSharedElementCallback.所有这些都来自支持库.
以下是我设置EnterTransition的方法:
private SharedElementCallback mCallback = new SharedElementCallback() { @Override public void onSharedElementStart(List<String> sharedElementNames,List<View> sharedElements,List<View> sharedElementSnapshots) { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if(sharedElements.size()>0) getWindow().setEnterTransition(makeEnterTransition(getWindow().getEnterTransition(),getSharedElement(sharedElements))); } } private View getSharedElement(List<View> sharedElements) { for (final View view : sharedElements) { if (view instanceof ImageView) { return view; } } return null; } };
解决方法
我不知道为什么需要TransitionManager.sRunningTransitions,但是如果从中移除Activity的DecorView,你的问题就会得到解决.按照代码示例,怎么做.在您的活动类中:
@Override protected void onDestroy() { super.onDestroy(); removeActivityFromTransitionManager(Activity activity); } private static void removeActivityFromTransitionManager(Activity activity) { if (Build.VERSION.SDK_INT < 21) { return; } Class transitionManagerClass = TransitionManager.class; try { Field runningTransitionsField = transitionManagerClass.getDeclaredField("sRunningTransitions"); runningTransitionsField.setAccessible(true); //noinspection unchecked ThreadLocal<WeakReference<ArrayMap<ViewGroup,ArrayList<Transition>>>> runningTransitions = (ThreadLocal<WeakReference<ArrayMap<ViewGroup,ArrayList<Transition>>>>) runningTransitionsField.get(transitionManagerClass); if (runningTransitions.get() == null || runningTransitions.get().get() == null) { return; } ArrayMap map = runningTransitions.get().get(); View decorView = activity.getWindow().getDecorView(); if (map.containsKey(decorView)) { map.remove(decorView); } } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } }