Утечка активности в Android

Я новичок в утечке канарейки и пытаюсь исправить несколько утечек памяти в моем приложении. В большинстве случаев у меня возникает утечка, когда я перехожу с экрана входа в систему с помощью булавки на любой другой экран в приложении. Вот канализационная свалка:

In com.exampleapp:4.5.0 (debug):62.
* com.exampleapp.activities.login.PinLoginActivity has leaked:
* GC ROOT thread java.lang.Thread.<Java Local> (named 'Thread-3')
* references com.android.tools.profiler.support.event.InputConnectionWrapper.mTarget
* references com.android.internal.widget.EditableInputConnection.mTextView
* references com.exampleapp.views.edittexts.PinEditText.mContext
* leaks com.exampleapp.activities.login.PinLoginActivity instance

* Retaining: 7.8 KB.
* Reference Key: 1036c14d-398c-45e5-a37f-55d9cd74d761
* Device: Google google Android SDK built for x86 sdk_google_phone_x86
* Android Version: 7.0 API: 24 LeakCanary: 1.5 00f37f5
* Durations: watch=5030ms, gc=133ms, heap dump=4614ms, analysis=127621ms

* Details:
* Instance of java.lang.Thread
|   static threadInitNumber = 1993
|   static threadSeqNumber = 2558
|   static NORM_PRIORITY = 5
|   static defaultUncaughtExceptionHandler = com.mixpanel.android.mpmetrics.ExceptionHandler@318432752 (0x12fae5f0)
|   static EMPTY_STACK_TRACE = java.lang.StackTraceElement[0]@1883982632 (0x704b4b28)
|   static $classOverhead = byte[476]@1884630209 (0x70552cc1)
|   static MIN_PRIORITY = 1
|   static SUBCLASS_IMPLEMENTATION_PERMISSION = java.lang.RuntimePermission@1883949688 (0x704aca78)
|   static NANOS_PER_MILLI = 1000000
|   static MAX_PRIORITY = 10
|   blocker = null
|   blockerLock = java.lang.Object@315005680 (0x12c69af0)
|   contextClassLoader = dalvik.system.PathClassLoader@315129136 (0x12c87d30)
|   daemon = false
|   eetop = 0
|   group = java.lang.ThreadGroup@1883966680 (0x704b0cd8)
|   inheritableThreadLocals = null
|   inheritedAccessControlContext = java.security.AccessControlContext@315005672 (0x12c69ae8)
|   lock = java.lang.Object@315005688 (0x12c69af8)
|   name = java.lang.String@315084256 (0x12c7cde0)
|   nativeParkEventPointer = 0
|   nativePeer = 2638205696
|   parkBlocker = null
|   parkState = 1
|   priority = 5
|   single_step = false
|   stackSize = 0
|   started = true
|   stillborn = false
|   target = com.android.tools.profiler.support.profilers.EventProfiler$InputConnectionHandler@314593072 (0x12c04f30)
|   threadLocalRandomProbe = 0
|   threadLocalRandomSecondarySeed = 0
|   threadLocalRandomSeed = 0
|   threadLocals = java.lang.ThreadLocal$ThreadLocalMap@320435344 (0x13197490)
|   threadQ = null
|   threadStatus = 0
|   tid = 467
|   uncaughtExceptionHandler = null
|   shadow$_klass_ = java.lang.Thread
|   shadow$_monitor_ = -2095673992
* Instance of com.android.tools.profiler.support.event.InputConnectionWrapper
|   static $classOverhead = byte[412]@315423745 (0x12ccfc01)
|   mMissingMethodFlags = 0
|   mMutable = false
|   mTarget = com.android.internal.widget.EditableInputConnection@325300400 (0x1363b0b0)
|   shadow$_klass_ = com.android.tools.profiler.support.event.InputConnectionWrapper
|   shadow$_monitor_ = 0
* Instance of com.android.internal.widget.EditableInputConnection
|   static TAG = java.lang.String@1887857896 (0x70866ce8)
|   static DEBUG = false
|   static $classOverhead = byte[413]@1890892489 (0x70b4bac9)
|   mBatchEditNesting = -1
|   mTextView = com.exampleapp.views.edittexts.PinEditText@323648512 (0x134a7c00)
|   mDefaultComposingSpans = null
|   mDummyMode = false
|   mEditable = null
|   mIMM = android.view.inputmethod.InputMethodManager@315217152 (0x12c9d500)
|   mKeyCharacterMap = null
|   mTargetView = com.exampleapp.views.edittexts.PinEditText@323648512 (0x134a7c00)
|   shadow$_klass_ = com.android.internal.widget.EditableInputConnection
|   shadow$_monitor_ = 0
* Instance of com.exampleapp.views.edittexts.PinEditText
|   static DEFAULT_CHARACTER_VERTICAL_PADDING = 10
|   static $change = null
|   static serialVersionUID = -9167688277854484912
|   static $classOverhead = byte[4216]@318918657 (0x13025001)
|   static PIN_CODE_LENGTH = 5
|   static DEFAULT_CHARACTER_HORIZONTAL_PADDING = 10
|   bounds = android.graphics.Rect@324427936 (0x135660a0)
|   characterBackgroundHeight = 33
|   characterBackgroundWidth = 54
|   characterCircleRadius = 16
|   characterHorizontalPadding = 11
|   characterPaint = android.graphics.Paint[5]@322122560 (0x13333340)
|   characterVerticalPadding = 11
|   emptyCharacterPaint = android.graphics.Paint@324343568 (0x13551710)
|   mBackgroundTintHelper = android.support.v7.widget.AppCompatBackgroundHelper@322122496 (0x13333300)
|   mTextHelper = android.support.v7.widget.AppCompatTextHelperV17@323529296 (0x1348aa50)
|   mAllowTransformationLengthChange = false
|   mAutoLinkMask = 0
|   mBoring = null
|   mBreakStrategy = 0
|   mBufferType = android.widget.TextView$BufferType@1890670224 (0x70b15690)
|   mChangeWatcher = android.widget.TextView$ChangeWatcher@320740464 (0x131e1c70)
|   mCharWrapper = null
|   mCurHintTextColor = 1627389952
|   mCurTextColor = -11246992
|   mCurrentSpellCheckerLocaleCache = null
|   mCursorDrawableRes = 17303397
|   mDeferScroll = -1
|   mDesiredHeightAtMeasure = -1
|   mDeviceProvisionedState = 0
|   mDrawables = null
|   mEditableFactory = android.text.Editable$Factory@1890661520 (0x70b13490)
|   mEditor = android.widget.Editor@323545568 (0x1348e9e0)
|   mEllipsize = null
|   mFilters = android.text.InputFilter[1]@320756400 (0x131e5ab0)
|   mFreezesText = false
|   mGravity = 8388627
|   mHighlightColor = 1716109245
|   mHighlightPaint = android.graphics.Paint@324343656 (0x13551768)
|   mHighlightPath = null
|   mHighlightPathBogus = true
|   mHint = null
|   mHintBoring = null
|   mHintLayout = null
|   mHintTextColor = android.content.res.ColorStateList@318855216 (0x13015830)
|   mHorizontallyScrolling = true
|   mHyphenationFrequency = 1
|   mIncludePad = true
|   mLastLayoutDirection = -1
|   mLastScroll = 0
|   mLayout = android.text.DynamicLayout@325012776 (0x135f4d28)
|   mLinkTextColor = android.content.res.ColorStateList@316287464 (0x12da29e8)
|   mLinksClickable = true
|   mListeners = java.util.ArrayList@325388080 (0x13650730)
|   mLocalesChanged = false
|   mMarquee = null
|   mMarqueeFadeMode = 0
|   mMarqueeRepeatLimit = 3
|   mMaxMode = 1
|   mMaxWidth = 2147483647
|   mMaxWidthMode = 2
|   mMaximum = 1
|   mMinMode = 1
|   mMinWidth = 0
|   mMinWidthMode = 2
|   mMinimum = 1
|   mMovement = android.text.method.ArrowKeyMovementMethod@315004712 (0x12c69728)
|   mOldMaxMode = 1
|   mOldMaximum = 1
|   mPreDrawListenerDetached = true
|   mPreDrawRegistered = true
|   mPreventDefaultMovement = false
|   mRestartMarquee = false
|   mSavedHintLayout = null
|   mSavedLayout = null
|   mSavedMarqueeModeLayout = null
|   mScroller = null
|   mShadowColor = 0
|   mShadowDx = 0.0
|   mShadowDy = 0.0
|   mShadowRadius = 0.0
|   mSingleLine = true
|   mSpacingAdd = 21.0
|   mSpacingMult = 1.0
|   mSpannableFactory = android.text.Spannable$Factory@1890661544 (0x70b134a8)
|   mTempRect = android.graphics.Rect@325601120 (0x13684760)
|   mText = android.text.SpannableStringBuilder@320953008 (0x13215ab0)
|   mTextColor = android.content.res.ColorStateList@318854976 (0x13015740)
|   mTextDir = android.text.TextDirectionHeuristics$TextDirectionHeuristicInternal@1890669624 (0x70b15438)
|   mTextEditSuggestionContainerLayout = 17367285
|   mTextEditSuggestionHighlightStyle = 16974923
|   mTextEditSuggestionItemLayout = 17367287
|   mTextPaint = android.text.TextPaint@324249968 (0x1353a970)
|   mTextSelectHandleLeftRes = 17303401
|   mTextSelectHandleRes = 17303403
|   mTextSelectHandleRightRes = 17303405
|   mTransformation = android.text.method.SingleLineTransformationMethod@315004736 (0x12c69740)
|   mTransformed = android.text.method.ReplacementTransformationMethod$SpannedReplacementCharSequence@325388032 (0x13650700)
|   mUserSetTextScaleX = false
|   mAccessibilityCursorPosition = -1
|   mAccessibilityDelegate = null
|   mAccessibilityTraversalAfterId = -1
|   mAccessibilityTraversalBeforeId = -1
|   mAccessibilityViewId = -1
|   mAnimator = null
|   mAttachInfo = null
|   mAttributes = null
|   mBackground = android.graphics.drawable.ColorDrawable@321007872 (0x13223100)
|   mBackgroundRenderNode = android.view.RenderNode@325599800 (0x13684238)
|   mBackgroundResource = 0
|   mBackgroundSizeChanged = true
|   mBackgroundTint = null
|   mBottom = 533
|   mCachingFailed = false
|   mClipBounds = null
|   mContentDescription = null
|   mContext = com.exampleapp.activities.login.PinLoginActivity@322213504 (0x13349680)
|   mCurrentAnimation = null
|   mDrawableState = int[2]@1884589496 (0x70548db8)
|   mDrawingCache = null
|   mDrawingCacheBackgroundColor = 0
|   mFloatingTreeObserver = null
|   mForegroundInfo = null
|   mFrameMetricsObservers = null
|   mGhostView = null
|   mHasPerformedLongPress = false
|   mID = 2131231080
|   mIgnoreNextUpEvent = false
|   mInContextButtonPress = false
|   mInputEventConsistencyVerifier = null
|   mKeyedTags = null
|   mLabelForId = -1
|   mLastIsOpaque = false
|   mLayerPaint = null
|   mLayerType = 0
|   mLayoutInsets = null
|   mLayoutParams = android.widget.LinearLayout$LayoutParams@323529688 (0x1348abd8)
|   mLeft = 382
|   mLeftPaddingDefined = false
|   mListenerInfo = android.view.View$ListenerInfo@324981952 (0x135ed4c0)
|   mLongClickX = NaN
|   mLongClickY = NaN
|   mMatchIdPredicate = null
|   mMatchLabelForPredicate = null
|   mMeasureCache = android.util.LongSparseLongArray@325575968 (0x1367e520)
|   mMeasuredHeight = 55
|   mMeasuredWidth = 315
|   mMinHeight = 0
|   mMinWidth = 0
|   mNestedScrollingParent = null
|   mNextFocusDownId = -1
|   mNextFocusForwardId = -1
|   mNextFocusLeftId = -1
|   mNextFocusRightId = -1
|   mNextFocusUpId = -1
|   mOldHeightMeasureSpec = 1073741879
|   mOldWidthMeasureSpec = 1073742139
|   mOutlineProvider = android.view.ViewOutlineProvider$1@1890661768 (0x70b13588)
|   mOverScrollMode = 1
|   mOverlay = null
|   mPaddingBottom = 21
|   mPaddingLeft = 0
|   mPaddingRight = 0
|   mPaddingTop = 21
|   mParent = android.widget.LinearLayout@323649536 (0x134a8000)
|   mPendingCheckForLongPress = null
|   mPendingCheckForTap = null
|   mPerformClick = null
|   mPointerIcon = null
|   mPrivateFlags = -2128607184
|   mPrivateFlags2 = 538125864
|   mPrivateFlags3 = 16
|   mRecreateDisplayList = false
|   mRenderNode = android.view.RenderNode@324265128 (0x1353e4a8)
|   mResources = android.content.res.Resources@324764064 (0x135b81a0)
|   mRight = 697
|   mRightPaddingDefined = false
|   mRunQueue = android.view.HandlerActionQueue@320958560 (0x13217060)
|   mScrollCache = null
|   mScrollIndicatorDrawable = null
|   mScrollX = 0
|   mScrollY = 50
|   mSendViewScrolledAccessibilityEvent = null
|   mSendViewStateChangedAccessibilityEvent = null
|   mSendingHoverAccessibilityEvents = false
|   mStartActivityRequestWho = null
|   mStateListAnimator = null
|   mSystemUiVisibility = 0
|   mTag = null
|   mTempNestedScrollConsumed = null
|   mTop = 478
|   mTouchDelegate = null
|   mTouchSlop = 21
|   mTransformationInfo = android.view.View$TransformationInfo@325602056 (0x13684b08)
|   mTransientStateCount = 0
|   mTransitionName = null
|   mUnscaledDrawingCache = null
|   mUnsetPressedState = null
|   mUserPaddingBottom = 21
|   mUserPaddingEnd = -2147483648
|   mUserPaddingLeft = 0
|   mUserPaddingLeftInitial = 0
|   mUserPaddingRight = 0
|   mUserPaddingRightInitial = 0
|   mUserPaddingStart = -2147483648
|   mVerticalScrollFactor = 0.0
|   mVerticalScrollbarPosition = 0
|   mViewFlags = 402931717
|   mWindowAttachCount = 1
|   shadow$_klass_ = com.exampleapp.views.edittexts.PinEditText
|   shadow$_monitor_ = 0
* Instance of com.exampleapp.activities.login.PinLoginActivity
|   static $change = null
|   static serialVersionUID = 2228880800337302055
|   static $classOverhead = byte[2336]@319320065 (0x13087001)
|   emailLogin = android.support.v7.widget.AppCompatButton@323791872 (0x134cac00)
|   pinEditText = com.exampleapp.views.edittexts.PinEditText@323648512 (0x134a7c00)
|   progress = com.exampleapp.views.layouts.custom.LoadingSpinner@323647488 (0x134a7800)
|   secureNumericKeyboard = com.exampleapp.views.layouts.login.SecureNumericKeyboard@323790848 (0x134ca800)
|   presenter = com.exampleapp.mvp.presenters.PinLoginPresenter@324839424 (0x135ca800)
|   changeApiAvailable = true
|   changeApiDialogShowing = false
|   chatMenuState = com.exampleapp.models.enums.ChatMenuState@314590224 (0x12c04410)
|   lastCallTimestamp = 0
|   loading = false
|   progressDialog = null
|   sd = com.squareup.seismic.ShakeDetector@321739136 (0x132d5980)
|   sensorManager = android.hardware.SystemSensorManager@320114328 (0x13148e98)
|   mDelegate = android.support.v7.app.AppCompatDelegateImplN@323260768 (0x13449160)
|   mResources = null
|   mThemeId = 2131755396
|   mCreated = true
|   mFragments = android.support.v4.app.FragmentController@320703600 (0x131d8c70)
|   mHandler = android.support.v4.app.FragmentActivity$1@321738912 (0x132d58a0)
|   mNextCandidateRequestIndex = 0
|   mPendingFragmentActivityResults = android.support.v4.util.SparseArrayCompat@324123376 (0x1351baf0)
|   mReallyStopped = true
|   mRequestedPermissionsFromFragment = false
|   mResumed = false
|   mRetaining = false
|   mStopped = true
|   mStartedActivityFromFragment = false
|   mStartedIntentSenderFromFragment = false
|   mExtraDataMap = android.support.v4.util.SimpleArrayMap@324121816 (0x1351b4d8)
|   mLifecycleRegistry = android.arch.lifecycle.LifecycleRegistry@321737536 (0x132d5340)
|   mActionBar = null
|   mActionModeTypeStarting = 0
|   mActivityInfo = android.content.pm.ActivityInfo@323228576 (0x134413a0)
|   mActivityTransitionState = android.app.ActivityTransitionState@322946824 (0x133fc708)
|   mApplication = com.exampleapp.ExampleApplication@315388256 (0x12cc7160)
|   mCalled = true
|   mChangeCanvasToTranslucent = false
|   mChangingConfigurations = false
|   mComponent = android.content.ComponentName@320713504 (0x131db320)
|   mConfigChangeFlags = 0
|   mCurrentConfig = android.content.res.Configuration@324787808 (0x135bde60)
|   mDecor = null
|   mDefaultKeyMode = 0
|   mDefaultKeySsb = null
|   mDestroyed = true
|   mDoReportFullyDrawn = false
|   mEatKeyUpEvent = false
|   mEmbeddedID = null
|   mEnableDefaultActionBarUp = false
|   mEnterTransitionListener = android.app.SharedElementCallback$1@1890667400 (0x70b14b88)
|   mExitTransitionListener = android.app.SharedElementCallback$1@1890667400 (0x70b14b88)
|   mFinished = true
|   mFragments = android.app.FragmentController@320703728 (0x131d8cf0)
|   mHandler = android.os.Handler@321737408 (0x132d52c0)
|   mHasCurrentPermissionsRequest = false
|   mIdent = 126901483
|   mInstanceTracker = android.os.StrictMode$InstanceTracker@320703712 (0x131d8ce0)
|   mInstrumentation = android.app.Instrumentation@315145952 (0x12c8bee0)
|   mIntent = android.content.Intent@322967864 (0x13401938)
|   mLastNonConfigurationInstances = null
|   mMainThread = android.app.ActivityThread@315146496 (0x12c8c100)
|   mManagedCursors = java.util.ArrayList@324121696 (0x1351b460)
|   mManagedDialogs = null
|   mMenuInflater = null
|   mParent = null
|   mReferrer = java.lang.String@320922528 (0x1320e3a0)
|   mResultCode = 0
|   mResultData = null
|   mResumed = false
|   mSearchEvent = null
|   mSearchManager = null
|   mStartedActivity = false
|   mStopped = true
|   mTaskDescription = android.app.ActivityManager$TaskDescription@321737440 (0x132d52e0)
|   mTemporaryPause = false
|   mTitle = java.lang.String@315092928 (0x12c7efc0)
|   mTitleColor = 0
|   mTitleReady = true
|   mToken = android.os.BinderProxy@321696960 (0x132cb4c0)
|   mTranslucentCallback = null
|   mUiThread = java.lang.Thread@1963345648 (0x750646f0)
|   mVisibleBehind = false
|   mVisibleFromClient = true
|   mVisibleFromServer = true
|   mVoiceInteractor = null
|   mWindow = com.android.internal.policy.PhoneWindow@314831776 (0x12c3f3a0)
|   mWindowAdded = true
|   mWindowManager = android.view.WindowManagerImpl@324122368 (0x1351b700)
|   mInflater = com.android.internal.policy.PhoneLayoutInflater@320850096 (0x131fc8b0)
|   mOverrideConfiguration = null
|   mResources = android.content.res.Resources@324764064 (0x135b81a0)
|   mTheme = android.content.res.Resources$Theme@320703104 (0x131d8a80)
|   mThemeResource = 2131755396
|   mBase = android.app.ContextImpl@324729344 (0x135afa00)
|   shadow$_klass_ = com.exampleapp.activities.login.PinLoginActivity
|   shadow$_monitor_ = -2097918190
* Excluded Refs:
| Field: android.view.Choreographer$FrameDisplayEventReceiver.mMessageQueue (always)
| Thread:FinalizerWatchdogDaemon (always)
| Thread:main (always)
| Thread:LeakCanary-Heap-Dump (always)
| Class:java.lang.ref.WeakReference (always)
| Class:java.lang.ref.SoftReference (always)
| Class:java.lang.ref.PhantomReference (always)
| Class:java.lang.ref.Finalizer (always)
| Class:java.lang.ref.FinalizerReference (always)

Я читал об утечках памяти, и большинство из них, кажется, происходят из статических ссылок и потоков, которые превышают жизненный цикл действия, но используя эти знания, я все еще не могу понять, в чем проблема. Вот код активности:

public class PinLoginActivity extends ExampleActivity<PinLogin.Presenter> implements PinLogin.View {

    @BindView(R.id.et_pin)
    EditText pinEditText;

    @BindView(R.id.keyboard)
    SecureNumericKeyboard secureNumericKeyboard;

    @BindView(R.id.progress)
    LoadingSpinner progress;

    @BindView(R.id.btn_email_login)
    Button emailLogin;

    /**
     * Creates intent for starting a new instance of this activity.
     *
     * @param context activity that will trigger this Intent
     * @return Intent for starting a new instance of this activity
     */
    public static Intent buildIntent(@NonNull Context context) {
        Intent intent = new Intent(context, PinLoginActivity.class);

        return intent;
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        changeApiAvailable = true;
        setContentView(R.layout.activity_pin_login);

        ButterKnife.bind(this);
        injectDependencies();

        secureNumericKeyboard.registerEditText(pinEditText);
    }

    /**
     * Helper method that injects Activity dependencies.
     */
    private void injectDependencies() {
        ExampleApplication.getUserComponent()
                .plus(new PinLoginModule(this))
                .inject(this);
    }

    @OnTextChanged(R.id.et_pin)
    public void onPinChange(CharSequence pin) {

    }

    @OnClick(R.id.btn_email_login)
    public void onEmailLoginClicked() {
        presenter.onEmailLogin();
    }

    //region PinLogin.View implementation.


    @Override
    public void clearPin() {
        pinEditText.setText(null);
    }

    @Override
    public void navigateToEmailLogin() {
        startActivity(EmailLoginActivity.buildIntent(this, false));
    }

    @Override
    public void navigateToHome(@NonNull UserData userData, @NonNull SessionService sessionService) {
        startActivity(IntentUtils.buildHomeIntent(this, userData, sessionService));
    }

    @Override
    public void navigateToVerifyEmail(String emailToVerify, String userId) {
        startActivity(VerifyEmailActivity.buildIntent(this, emailToVerify, userId, true));
        finish();
    }

    @Override
    public void showLoading(LoadingState state, View otherView) {
        switch (state) {
            case LOADING:
                pinEditText.setVisibility(View.INVISIBLE);
                emailLogin.setVisibility(View.INVISIBLE);
                secureNumericKeyboard.setVisibility(View.INVISIBLE);
                progress.setVisibility(View.VISIBLE);
                break;
            case FAILED:
                pinEditText.setVisibility(View.VISIBLE);
                emailLogin.setVisibility(View.VISIBLE);
                secureNumericKeyboard.setVisibility(View.VISIBLE);
                progress.setVisibility(View.INVISIBLE);
                break;
            case COMPLETE:
                pinEditText.setVisibility(View.INVISIBLE);
                emailLogin.setVisibility(View.INVISIBLE);
                secureNumericKeyboard.setVisibility(View.INVISIBLE);
                progress.setVisibility(View.VISIBLE);
                break;
            default:
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        secureNumericKeyboard.unregisterEditText(pinEditText);
    }

    public boolean shouldClearActivities() {
        return true;
    }

    //endregion
}

Пожалуйста, кто-нибудь может указать мне правильное направление, чтобы исправить эту утечку памяти? Я могу опубликовать больше кода, если это необходимо.

0 ответов

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