W/系统:资源调用释放失败

2022-09-01 04:25:50

正如标题所说。当我在我的应用程序上使用AndroidStudio的控制台时,它会显示:

W/系统:资源调用释放失败。

有时它被说了好几次。我知道这意味着什么,但我已经多次检查了几乎2k行的代码,但我对关闭/释放我错过了什么一无所知。

有没有办法从控制台扩展此信息?或者您如何定位资源是什么或当它无法关闭时?欢迎任何想法。谢谢。


答案 1

@guest的答案是有效的,但是您可以使用严格模式实现完全相同的效果,而无需诉诸反射。具体来说,像这样:

StrictMode.setVmPolicy(new VmPolicy.Builder()
                 .detectLeakedClosableObjects()
                 .penaltyLog()
                 .build());

一般来说,严格模式可以为您做更多的事情(请参阅上面的doc链接),对于默认设置,您需要做的就是:

StrictMode.enableDefaults();  # <-- This includes warning on leaked closeables

要“尽快”启用严格模式,您可以将上述代码选项中的任何一个添加到应用程序类的构造函数中,例如:

public class MyApp extends Application {

    public MyApp() {
        if(BuildConfig.DEBUG)
            StrictMode.enableDefaults();
    }

}

请注意,除了创建上面的类之外,您还需要告诉 Android 您已在 中创建了一个自定义应用程序类(以便在应用程序进程启动时创建它的实例,而不是 Android 创建默认类)。您需要添加/修改标记的属性以指向自定义应用程序类的完全解析的包路径(在本例中):AndroidManifest.xmlApplicationandroid:name<application>MyApp

<application
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:name="com.example.app.MyApp"  <-- IMPORTANT PART: ADAPT FOR YOUR ACTUAL PROJECT
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

答案 2

此消息来自 。调试时,您可以将其设置为在创建资源时创建堆栈跟踪,以便可以跟踪哪些对象未关闭。dalvik.system.CloseGuard

它不是框架API的一部分,所以我使用反射来打开它:

try {
    Class.forName("dalvik.system.CloseGuard")
            .getMethod("setEnabled", boolean.class)
            .invoke(null, true);
} catch (ReflectiveOperationException e) {
    throw new RuntimeException(e);
}

更多信息: https://wh0.github.io/2020/08/12/closeguard.html


推荐