mukeshsolanki / android-otpview-pinview

A custom view to enter otp of different sizes used usually in cases of authentication.
MIT License
689 stars 208 forks source link

LeakCanary found a memory leak in OtpView #155

Closed lsamaria closed 9 months ago

lsamaria commented 11 months ago

Subject of the issue

LeakCanary found a memory leak in OtpView.

├─ com.mukeshsolanki.OtpView instance
│    Leaking: YES (View.mContext references a destroyed activity)

Steps to reproduce

1- Add these LeakCanary and OtpView versions to your gradle file:

• debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12' • implementation 'com.github.mukeshsolanki.android-otpview-pinview:otpview:3.1.0'

I'm using a physical device to test on, specifically a:

• LG Style 6 • running Android Version 10 • Software version Q730TM11c • SDK 29

2- Use otpView as intended to enter a SMS code inside an activity. After the smsCode is successfully sent to the server (I use Firebase), finish() the activity. LeakCanary will report a memory leak after the activity is finished.

Expected behaviour

A memory leak shouldn't occur

Actual behaviour

A memory leak occurs after the activity is finished.

Stack Trace:

┬───
│ GC Root: System class
│
├─ android.view.inputmethod.InputMethodManager class
│    Leaking: NO (InputMethodManager↓ is not leaking and a class is never
│    leaking)
│    ↓ static InputMethodManager.sInstance
├─ android.view.inputmethod.InputMethodManager instance
│    Leaking: NO (InputMethodManager is a singleton)
│    Library leak match: instance field android.view.inputmethod.
│    InputMethodManager#mLastFocusView
│    ↓ InputMethodManager.mLastFocusView
│                         ~~~~~~~~~~~~~~
├─ com.mukeshsolanki.OtpView instance
│    Leaking: YES (View.mContext references a destroyed activity)
│    Retaining 150.9 kB in 1945 objects
│    View is part of a window view hierarchy
│    View.mAttachInfo is null (view detached)
│    View.mID = R.id.otp_view
│    View.mWindowAttachCount = 1
│    mContext instance of package.SmsActivity with mDestroyed =
│    true
│    ↓ View.mContext
╰→ package.SmsActivity instance
​     Leaking: YES (ObjectWatcher was watching this because com.mycompany
​     myapp.SmsActivity received Activity#onDestroy() callback and
​     Activity#mDestroyed is true)
​     Retaining 14.1 kB in 392 objects
​     key = 59aed0b3-8b92-4635-89ee-c1042876b275
​     watchDurationMillis = 28296
​     retainedDurationMillis = 23296
​     mApplication instance of package.MyApplication
​     mBase instance of androidx.appcompat.view.ContextThemeWrapper

METADATA

Build.VERSION.SDK_INT: 29
Build.MANUFACTURER: LGE
LeakCanary version: 2.12
App process name: package
Class count: 20704
Instance count: 167323
Primitive array count: 107953
Object array count: 24783
Thread count: 79
Heap total bytes: 21200942
Bitmap count: 20
Bitmap total bytes: 503976
Large bitmap count: 0
Large bitmap total bytes: 0
Db 1: open /data/user/0/package/databases/com.google.android.
datatransport.events
Db 2: closed /data/user/0/com.mycompany.
myapp/databases/google_app_measurement_local.db
Db 3: open /data/user/0/package/no_backup/androidx.work.workdb
Db 4: open /data/user/0/package/databases/leaks.db
Db 5: closed /data/user/0/com.mycompany
myapp/databases/google_app_measurement_local.db
Db 6: closed /data/user/0/com.mycompany.
myapp/databases/google_app_measurement_local.db
Db 7: closed /data/user/0/com.mycompany.
myapp/databases/google_app_measurement_local.db
Db 8: closed /data/user/0/com.mycompany.
myapp/databases/google_app_measurement_local.db
Db 9: closed /data/user/0/com.mycompany.
myapp/databases/google_app_measurement_local.db
Db 10: closed /data/user/0/com.mycompany.
myapp/databases/google_app_measurement_local.db
Db 11: closed /data/user/0/com.mycompany.
myapp/databases/google_app_measurement_local.db
Db 12: closed /data/user/0/com.mycompany.
myapp/databases/google_app_measurement_local.db
Stats: LruCache[maxSize=3000,hits=55906,misses=130913,hitRate=29%]
RandomAccess[bytes=6447938,reads=130913,travel=49373041312,range=25390374,size=3
1529082]
Analysis duration: 25900 ms

Activity Code::

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding.otpView.setOtpCompletionListener { smsCode ->

            // send smsCode to Firebase
        }
}

override fun onDestroy() {
        super.onDestroy()

        binding.otpView.setOtpCompletionListener(null) // I've also commented this out and the leak still occurs
}

XML file

<com.mukeshsolanki.OtpView
        android:id="@+id/otp_view"
        android:focusableInTouchMode="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="200dp"
        android:hint="Enter the SMS verification code sent to your phone"
        android:inputType="number"
        android:textAllCaps="true"
        android:textSize="40sp"
        android:textColor="@android:color/black"
        android:textColorHint="#757575"
        app:OtpHideLineWhenFilled="false"
        app:OtpItemCount="6"
        app:OtpLineColor="@color/gray"
        app:OtpState_filled="true"
        app:OtpViewType="line"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />
stale[bot] commented 9 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 9 months ago

This has been closed with no activity