我们注意到在搭载 Android 13 (One Ui 5) 的三星设备上运行 Webview 的活动中存在内存泄漏。下面是 LeakCanary 报告。
│ GC Root: Global variable in native code
│
├─ J1 instance
│ Leaking: UNKNOWN
│ Retaining 680,3 kB in 15862 objects
│ ↓ WindowAndroid.p
│ ~
├─ b30 instance
│ Leaking: UNKNOWN
│ Retaining 679,2 kB in 15820 objects
│ ↓ b30.b
│ ~
├─ com.android.internal.policy.PhoneWindow instance
│ Leaking: YES (Window#mDestroyed is true)
│ Retaining 679,2 kB in 15819 objects
│ mContext instance of br.com.gabba.myapp.presentation.MainActivity with mDestroyed = true
│ mOnWindowDismissedCallback instance of br.com.gabba.myapp.presentation.MainActivity with mDestroyed = true
│ ↓ Window.mContext
╰→ br.com.gabba.myapp.presentation.MainActivity instance
Leaking: YES (ObjectWatcher was watching this because br.com.gabba.myapp.presentation.MainActivity received
Activity#onDestroy() callback and Activity#mDestroyed is true)
Retaining 538,5 kB in 13567 objects
key = 126214f9-52c8-4a22-af8f-58abebe69b1e
watchDurationMillis = 8833
retainedDurationMillis = 3833
mApplication instance of br.com.gabba.myapp.MyApplication
mBase instance of androidx.appcompat.view.ContextThemeWrapper
METADATA
Build.VERSION.SDK_INT: 33
Build.MANUFACTURER: samsung
LeakCanary version: 2.10
App process name: br.com.gabba.myapp
Class count: 31572
Instance count: 320386
Primitive array count: 202503
Object array count: 43587
Thread count: 111
Heap total bytes: 39404391
Bitmap count: 6
Bitmap total bytes: 5589062
Large bitmap count: 0
Large bitmap total bytes: 0
Db 1: open /data/user/0/br.com.gabba.myapp/databases/leaks.db
Db 2: closed /data/user/0/br.com.gabba.myapp/databases/google_app_measurement_local.db
Db 3: open /data/user/0/br.com.gabba.myapp/databases/com.google.android.datatransport.events
Db 4: open /data/user/0/br.com.gabba.myapp/databases/com.microsoft.appcenter.persistence
Db 5: open /data/user/0/br.com.gabba.myapp/no_backup/androidx.work.workdb
Db 6: closed /data/user/0/br.com.gabba.myapp/databases/google_app_measurement_local.db
Db 7: closed /data/user/0/br.com.gabba.myapp/databases/google_app_measurement_local.db
Db 8: closed /data/user/0/br.com.gabba.myapp/databases/google_app_measurement_local.db
Db 9: closed /data/user/0/br.com.gabba.myapp/databases/google_app_measurement_local.db
Db 10: closed /data/user/0/br.com.gabba.myapp/databases/google_app_measurement_local.db
Db 11: closed /data/user/0/br.com.gabba.myapp/databases/google_app_measurement_local.db
Count of retained yet cleared: 1 KeyedWeakReference instances
Stats: LruCache[maxSize=3000,hits=133355,misses=256075,hitRate=34%]
RandomAccess[bytes=12990793,reads=256075,travel=148042143598,range=46289982,size=57036190]
Analysis duration: 14673 ms
如果我们在 layout xml 中有 webview 组件并在 activity 中对其进行 inflate,就会出现问题。下面的例子:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="br.com.gabba.myapp.presentation.WebViewActivity"
tools:viewBindingIgnore="true">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay"
android:background="@drawable/bg_header"
android:gravity="bottom"
app:elevation="0dp">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:paddingStart="8dp"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:contentInsetStartWithNavigation="0dp"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:title="@string/app_name"
app:titleTextAppearance="@style/Toolbar.TitleTextExterno" />
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<RelativeLayout
android:id="@+id/areaFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:id="@+id/loadingContainer"
style="@style/ProgressBar"
android:layout_gravity="center"
app:mpb_progressStyle="circular"
app:mpb_useIntrinsicPadding="false" />
<TextView
android:id="@+id/status"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_gravity="center"
android:layout_marginTop="40dp"
android:text="Status"
android:visibility="gone" />
</FrameLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Activity 从 androidx.appcompat:appcompat:1.6.1 扩展 AppCompatActivity
问题已在一台设备上复制:Galaxy S20 FE SM-G780G/DS 一个 UI 5.0 安卓 13
该问题尚未在其他版本的 Android 或其他制造商运行 Android 13 的设备(例如 Pixel 4)上重现。
这个问题的解决方案是什么?