问题描述
我目前正在使用 Android Studio 使用壁纸服务开发动态壁纸。
经过验证,发现在执行以下操作时出现内存泄漏并消失(?),但不知道解决方案。
如何解决内存泄漏?
- 运行活动 (如果没有设置 android.intent.category.LAUNCHER 的 Activity,在我的情况下 Leak Canary 将启动。) ,然后关闭。
- 将我的动态壁纸设置为“主屏幕”和“锁定屏幕”,然后关闭。(背景将为黑色。)
- 在 Android Studio 中启动新的分析器会话以检查内存。
- 将其他壁纸(例如纯色)设置为主屏幕和锁定屏幕,然后关闭。(背景会改变)
Leak Canary 检测并通知您泄漏。(此时转储的数据将在后面描述) 您还可以检查内存是否保留在 Profiler 中。
但如果我忽略通知,启动 Leak Canary 并关闭它,内存分析器会变为 0 并停止。
如果您选择之前显示的 Leak Canary 通知,您将看到以下文本: 「所有保留的对象都被垃圾收集了点击即可关闭」
Wallpaper.java
package Wallpaper;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
public class Wallpaper extends WallpaperService{
@Override
public Engine onCreateEngine() {
return new Engine();
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.wallpapertest">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.WallpaperTest">
<!-- <activity-->
<!-- android:name=".MainActivity"-->
<!-- android:label="@string/app_name"-->
<!-- android:theme="@style/Theme.WallpaperTest.NoActionBar">-->
<!-- <intent-filter>-->
<!-- <action android:name="android.intent.action.MAIN" />-->
<!-- <category android:name="android.intent.category.LAUNCHER" />-->
<!-- </intent-filter>-->
<!-- </activity>-->
<service
android:name="Wallpaper"
android:label="TestWallpaper"
android:permission="android.permission.BIND_WALLPAPER">
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
</intent-filter>
<Meta-data
android:name="android.service.wallpaper"
android:resource="@xml/wallpaper" />
</service>
</application>
</manifest>
被 Leak Canary 抛弃
┬───
│ GC Root: Global variable in native code
│
├─ android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper instance
│ Leaking: UNKNowN
│ Retaining 614 B in 3 objects
│ this$0 instance of com.example.wallpapertest.Wallpaper
│ ↓ WallpaperService$IWallpaperEngineWrapper.this$0
│ ~~~~~~
╰→ com.example.wallpapertest.Wallpaper instance
Leaking: YES (ObjectWatcher was watching this because com.example.
wallpapertest.Wallpaper received Service#onDestroy() callback)
Retaining 1.4 kB in 16 objects
key = 258eebec-e068-4a18-8b80-f4044dd74ca4
watchDurationMillis = 17673
retainedDurationMillis = 11652
mApplication instance of android.app.Application
mBase instance of android.app.ContextImpl
MetaDATA
Build.VERSION.SDK_INT: 30
Build.MANUFACTURER: Google
LeakCanary version: 2.6
App process name: com.example.wallpapertest
Stats: LruCache[maxSize=3000,hits=1850,misses=54308,hitRate=3%]
RandomAccess[bytes=2722909,reads=54308,travel=19446709706,range=16694011,size=22
214598]
Heap dump reason: user request
Analysis duration: 634134 ms
build.gradle(:app)
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
buildToolsversion "30.0.3"
defaultConfig {
applicationId "com.example.wallpapertest"
minSdkVersion 28
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
//for LeakCanary
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunnerArgument "listener","leakcanary.FailTestOnLeakRunListener"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.navigation:navigation-fragment:2.3.5'
implementation 'androidx.navigation:navigation-ui:2.3.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
//for LeakCanary
def leakcanary_version = '2.6'
debugImplementation "com.squareup.leakcanary:leakcanary-android:$leakcanary_version"
androidTestImplementation "com.squareup.leakcanary:leakcanary-android-instrumentation:$leakcanary_version"
}
其他
- Android Studio 4.2.1
- AVD Pixel3a API30(Android11)
- 单击分析器的内存图会导致 IDE 内部错误,因此我看不到详细信息。
- % java --version
openjdk 11.0.8 2020-07-14
OpenJDK 运行时环境(构建 11.0.8+10-b944.6916264)
OpenJDK 64 位服务器 VM(构建 11.0.8+10-b944.6916264,混合模式)
我怀疑墙纸服务有一些参考。 我创建了另一个activity作为试用,执行了1-4,检查了内存泄漏,然后打开关闭创建的activity,泄漏消失了。
我是初学者,非常想听听您的意见。欢迎提出任何想法或建议。
分析器图像 [1]:https://i.stack.imgur.com/wQvts.png
添加: 显然,启动 LeakCanary 以外的活动可以解决泄漏问题。 这是 Android 规范,可能不是内存泄漏。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)