Memory Leak MediaControllerCompat

I have a MediaControllerCompat that creates an instance when a MediaSession connection is MediaSession . When this connection is made, I create a MediaControllerCompat as follows:

 MediaControllerCompat mediaController = new MediaControllerCompat(this, token); MediaControllerCompat.setMediaController(this, mediaController); 

Token receives from MediaSession .

All pushings of this button back detect a leak. I do not have a callback / listener registered on MediaControllerCompat . I have already tried setting MediaController to null by the type of activity onDestroy() , without success.

 MediaControllerCompat.setMediaController(this, null); 

Follow below in LeakCanary magazine.

 D/LeakCanary: * com.me.PlaybackFullscreenActivity has leaked: D/LeakCanary: * GC ROOT android.os.ResultReceiver$MyResultReceiver.this$0 D/LeakCanary: * references android.support.v4.media.session.MediaControllerCompat$MediaControllerImplApi21$1.this$0 (anonymous subclass of android.os.ResultReceiver) D/LeakCanary: * references android.support.v4.media.session.MediaControllerCompat$MediaControllerImplApi23.mControllerObj D/LeakCanary: * references android.media.session.MediaController.mContext D/LeakCanary: * leaks com.me.ui.playback.PlaybackFullscreenActivity instance D/LeakCanary: * Retaining: 54 KB. D/LeakCanary: * Reference Key: 004ed9cd-c668-4d23-9ee6-cecad1b980a5 D/LeakCanary: * Device: unknown Android Android SDK built for x86_64 sdk_google_phone_x86_64 D/LeakCanary: * Android Version: 7.1 API: 25 LeakCanary: 1.5 00f37f5 D/LeakCanary: * Durations: watch=5018ms, gc=115ms, heap dump=1936ms, analysis=6011ms D/LeakCanary: * Details: D/LeakCanary: * Instance of android.os.ResultReceiver$MyResultReceiver D/LeakCanary: | this$0 = android.support.v4 .media.session.MediaControllerCompat$MediaControllerImplApi21$1@ 322318080 (0x13362f00) D/LeakCanary: | mDescriptor = java.lang.String@1887101392 (0x707ae1d0) D/LeakCanary: | mObject = -813433536 D/LeakCanary: | mOwner = android.os.ResultReceiver$MyResultReceiver@322318176 (0x13362f60) D/LeakCanary: | shadow$_klass_ = android.os.ResultReceiver$MyResultReceiver D/LeakCanary: | shadow$_monitor_ = 0 D/LeakCanary: * Instance of android.support.v4.media.session.MediaControllerCompat$MediaControllerImplApi21$1 D/LeakCanary: | this$0 = android.support. v4.media.session.MediaControllerCompat$MediaControllerImplApi23@ 322317952 (0x13362e80) D/LeakCanary: | mHandler = android.os.Handler@322318144 (0x13362f40) D/LeakCanary: | mLocal = true D/LeakCanary: | mReceiver = android.os.ResultReceiver$MyResultReceiver@322318176 (0x13362f60) D/LeakCanary: | shadow$_klass_ = android.support.v4.media.session.MediaControllerCompat$MediaControllerImplApi21$1 D/LeakCanary: | shadow$_monitor_ = 0 D/LeakCanary: * Instance of android.support.v4.media.session.MediaControllerCompat$MediaControllerImplApi23 D/LeakCanary: | mCallbackMap = java.util.HashMap@322587040 (0x133a49a0) D/LeakCanary: | mControllerObj = android.media.session.MediaController@322587088 (0x133a49d0) D/LeakCanary: | mExtraBinder = android.support.v4.medi a.session.MediaSessionCompat$MediaSessionImplApi21$ExtraSession@ 319823424 (0x13101e40) D/LeakCanary: | mPendingCallbacks = null D/LeakCanary: | shadow$_klass_ = android.support.v4.media.session.MediaControllerCompat$MediaControllerImplApi23 D/LeakCanary: | shadow$_monitor_ = 0 D/LeakCanary: * Instance of android.media.session.MediaController D/LeakCanary: | static MSG_UPDATE_EXTRAS = 7 D/LeakCanary: | static MSG_DESTROYED = 8 D/LeakCanary: | static MSG_UPDATE_VOLUME = 4 D/LeakCanary: | static MSG_UPDATE_QUEUE_TITLE = 6 D/LeakCanary: | static MSG_UPDATE_PLAYBACK_STATE = 2 D/LeakCanary: | static $staticOverhead = byte[72]@317243393 (0x12e8c001) D/LeakCanary: | static MSG_UPDATE_QUEUE = 5 D/LeakCanary: | static MSG_EVENT = 1 D/LeakCanary: | static TAG = java.lang.String@1886292312 (0x706e8958) D/LeakCanary: | static MSG_UPDATE_METADATA = 3 D/LeakCanary: | mCallbacks = java.util.ArrayList@322318048 (0x13362ee0) D/LeakCanary: | mCbRegistered = false D/LeakCanary: | mCbStub = android.media.session.MediaController$CallbackStub@322317984 (0x13362ea0) D/LeakCanary: | mContext = com.me.ui.playback.PlaybackFullscreenActivity@322837504 (0x133e1c00) D/LeakCanary: | mLock = java.lang.Object@319489728 (0x130b06c0) D/LeakCanary: | mPackageName = null D/LeakCanary: | mSessionBinder = android.media.session.ISessionController$Stub$Proxy@319491728 (0x130b0e90) D/LeakCanary: | mTag = null D/LeakCanary: | mToken = android.media.session.MediaSession$Token@319489760 (0x130b06e0) D/LeakCanary: | mTransportControls = android.media.session.MediaController$TransportControls@31948974 4 (0x130b06d0) D/LeakCanary: | shadow$_klass_ = android.media.session.MediaController D/LeakCanary: | shadow$_monitor_ = 0 D/LeakCanary: * Instance of com.me.ui.playback.PlaybackFullscreenActivity D/LeakCanary: | static $staticOverhead = byte[16]@317706241 (0x12efd001) D/LeakCanary: | static serialVersionUID = 0 D/LeakCanary: | static $change = null D/LeakCanary: | mToolbar = android.support.v7.widget.Toolbar@321094656 (0x13238400) D/LeakCanary: | playbackFragment = com.me.ui.playback.PlaybackFragment@318524080 (0x12fc4ab0) D/LeakCanary: | mDelegate = android.support.v7.app.AppCompatDelegateImplV23@320052000 (0x13139b20) D/LeakCanary: | mEatKeyUpEvent = false D/LeakCanary: | mResources = null D/LeakCanary: | mThemeId = 2131427393 D/LeakCanary: | mCreated = true D/LeakCanary: | mFragments = android.support.v4.app.FragmentController@323740768 (0x134be460) D/LeakCanary: | mHandler = android.support.v4.app.FragmentActivity$1@323839264 (0x134d6520) D/LeakCanary: | mNextCandidateRequestIndex = 0 D/LeakCanary: | mOptionsMenuInvalidated = false D/LeakCanary: | mPendingFragmentActivityResults = android.support.v4.util.SparseArrayCompat@323840160 (0x134d68a0) D/LeakCanary: | mReallyStopped = true D/LeakCanary: | mRequestedPermissionsFromFragment = false D/LeakCanary: | mResumed = false D/LeakCanary: | mRetaining = false D/LeakCanary: | mStopped = true D/LeakCanary: | mStartedActivityFromFragment = false D/LeakCanary: | mStartedIntentSenderFromFragment = false D/LeakCanary: | mExtraDataMap = android.support.v4.util.SimpleArrayMap@323839232 (0x134d6500) D/LeakCanary: | mActionBar = null D/LeakCanary: | mActionModeTypeStarting = 0 D/LeakCanary: | mActivityInfo = android.content.pm.ActivityInfo@319807616 (0x130fe080) D/LeakCanary: | mActivityTransitionState = android.app.ActivityTransitionState@323795264 (0x134cb940) D/LeakCanary: | mApplication = com.me.MainApplication@314898704 (0x12c4f910) D/LeakCanary: | mCalled = true D/LeakCanary: | mChangeCanvasToTranslucent = false D/LeakCanary: | mChangingConfigurations = false D/LeakCanary: | mComponent = android.content.ComponentName@323825776 (0x134d3070) D/LeakCanary: | mConfigChangeFlags = 0 D/LeakCanary: | mCurrentConfig = android.content.res.Configuration@323855456 (0x134da460) D/LeakCanary: | mDecor = null D/LeakCanary: | mDefaultKeyMode = 0 D/LeakCanary: | mDefaultKeySsb = null D/LeakCanary: | mDestroyed = true D/LeakCanary: | mDoReportFullyDrawn = false D/LeakCanary: | mEmbeddedID = null D/LeakCanary: | mEnableDefaultActionBarUp = false D/LeakCanary: | mEnterTransitionListener = android.app.SharedElementCallback$1@1888376616 (0x708e5728) D/LeakCanary: | mExitTransitionListener = android.app.SharedElementCallback$1@1888376616 (0x708e5728) D/LeakCanary: | mFinished = true D/LeakCanary: | mFragments = android.app.FragmentController@323740720 (0x134be430) D/LeakCanary: | mHandler = android.os.Handler@323839136 (0x134d64a0) D/LeakCanary: | mIdent = 169286722 D/LeakCanary: | mInstanceTracker = android.os.StrictMode$InstanceTracker@323740736 (0x134be440) D/LeakCanary: | mInstrumentation = android.app.Instrumentation@315044816 (0x12c733d0) D/LeakCanary: | mIntent = android.content.Intent@323821632 (0x134d2040) D/LeakCanary: | mLastNonConfigurationInstances = null D/LeakCanary: | mMainThread = android.app.ActivityThread@314791872 (0x12c357c0) D/LeakCanary: | mManagedCursors = java.util.ArrayList@323839168 (0x134d64c0) D/LeakCanary: | mManagedDialogs = null D/LeakCanary: | mMenuInflater = null D/LeakCanary: | mParent = null D/LeakCanary: | mReferrer = java.lang.String@323822208 (0x134d2280) D/LeakCanary: | mResultCode = 0 D/LeakCanary: | mResultData = null D/LeakCanary: | mResumed = false D/LeakCanary: | mSearchEvent = null D/LeakCanary: | mSearchManager = null D/LeakCanary: | mStartedActivity = false D/LeakCanary: | mStopped = true D/LeakCanary: | mTemporaryPause = false D/LeakCanary: | mTitle = java.lang.String@314691776 (0x12c1d0c0) D/LeakCanary: | mTitleColor = 0 D/LeakCanary: | mTitleReady = true D/LeakCanary: | mToken = android.os.BinderProxy@323829824 (0x134d4040) D/LeakCanary: | mTranslucentCallback = null D/LeakCanary: | mUiThread = java.lang.Thread@1955762776 (0x74929258) D/LeakCanary: | mVisibleBehind = false D/LeakCanary: | mVisibleFromClient = true D/LeakCanary: | mVisibleFromServer = true D/LeakCanary: | mVoiceInteractor = null D/LeakCanary: | mWindow = com.android.internal.policy.PhoneWindow@317655136 (0x12ef0860) D/LeakCanary: | mWindowAdded = true D/LeakCanary: | mWindowManager = android.view.WindowManagerImpl@323839680 (0x134d66c0) D/LeakCanary: | mInflater = com.android.internal.policy.PhoneLayoutInflater@323776416 (0x134c6fa0) D/LeakCanary: | mOverrideConfiguration = null D/LeakCanary: | mResources = android.content.res.Resources@315044736 (0x12c73380) D/LeakCanary: | mTheme = android.content.res.Resources$Theme@323839712 (0x134d66e0) D/LeakCanary: | mThemeResource = 2131427393 D/LeakCanary: | mBase = android.app.ContextImpl@319796480 (0x130fb500) D/LeakCanary: | shadow$_klass_ = com.me.ui.playback.PlaybackFullscreenActivity D/LeakCanary: | shadow$_monitor_ = 1293121552 D/LeakCanary: * Excluded Refs: D/LeakCanary: | Field: android.view.inputmethod.InputMethodManager.mNextServedView D/LeakCanary: | Field: android.view.inputmethod.InputMethodManager.mServedView D/LeakCanary: | Field: android.view.inputmethod.InputMethodManager.mServedInputConnection D/LeakCanary: | Field: android.view.inputmethod.InputMethodManager.mCurRootView D/LeakCanary: | Field: android.os.UserManager.mContext D/LeakCanary: | Field: android.net.ConnectivityManager.sInstance D/LeakCanary: | Field: android.view.Choreographer$FrameDisplayEventReceiver.mMessageQueue (always) D/LeakCanary: | Thread:FinalizerWatchdogDaemon (always) D/LeakCanary: | Thread:main (always) D/LeakCanary: | Thread:LeakCanary-Heap-Dump (always) D/LeakCanary: | Class:java.lang.ref.WeakReference (always) D/LeakCanary: | Class:java.lang.ref.SoftReference (always) D/LeakCanary: | Class:java.lang.ref.PhantomReference (always) D/LeakCanary: | Class:java.lang.ref.Finalizer (always) D/LeakCanary: | Class:java.lang.ref.FinalizerReference (always) 

Can someone help me?

Thanks in advance.

+5
source share
2 answers

This leak has been fixed and released in the support library 25.2.0. Font: issuetracker

+5
source

MediaControllerCompat.setMediaController() creates controllerObj instances . This object is then used to execute setMediaController(activity, controllerObj) . After that, I see no seams that controllerObj might not leak. In other words, it seems that you need to take care of abandoning this object yourself:

 MediaSessionCompat mediaSessionCompat = ...; MediaController mediaController = (MediaController) mediaSessionCompat.getController().getMediaController(); // explicitly nulling out MediaController mediaController = null; 

Note that executing MediaControllerCompat.setMediaController(this, null) will not preempt the previously specified object, but simply update the current instance with a new one. But controllerObj keeps a solid link to hosting activity, and no one bothered to reset.

+2
source

Source: https://habr.com/ru/post/1262080/


All Articles