不会调用ComponentCallbacks2中的onTrimMemory()

时间:2016-07-22 17:56:45

标签: java android android-lifecycle

我已经实现了ComponentCallbacks2,并且永远不会调用onTrimMemory。我正在尝试使用Application类和我的自定义生命周期来管理内存。对此有任何帮助表示赞赏。

for the_match in matches:
    print (the_match)

我有一个从MemoryManager类调用我的接口的应用程序类。

public class MemoryManager implements ComponentCallbacks2 {
    private static List<MemoryInfo> memInfoList = new ArrayList<>();

    public interface MemoryInfo {
        void releaseMemory();
    }

    public static void registerMemoryListener(MemoryInfo memoryInfo) {
        memInfoList.add(memoryInfo);
    }

    public static void unregisterMemoryListener(MemoryInfo memoryInfo) {
        memInfoList.remove(memoryInfo);
    }

    @Override
    public void onTrimMemory(int level) {
        Log.i("TEST", "onTrimMemory called"); // does not get called
        switch (level) {
            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
                try {
                    for (int i = memInfoList.size() - 1; i >= 0; i--) {
                        try {
                            memInfoList.get(i).releaseMemory(); // is this correct implementation?
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
                // I added logs here, it does not get reached
                break;
            default:
                break;
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        // do nothing
    }

    @Override
    public void onLowMemory() {
        // will log when there is log memory
    }

我的主要活动就是跟踪生命周期。这工作正常。我的生命周期方法如下所示:

public class TestApplication extends Application implements ActivityLifecycleCallback, MemoryManager.MemoryInfo {

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onStart(Activity activity) {
        Log.i(TAG, "onStart() called :: " + activity.getLocalClassName());
    }

    @Override
    public void onResume(Activity activity) {
        Log.i(TAG, "onResume called :: " + activity.getLocalClassName());
        MemoryManager.registerMemoryListener(this);
    }

    @Override
    public void onPause(Activity activity) {
        Log.i(TAG, "onPause called :: " + activity.getLocalClassName());
    }

    @Override
    public void onStop(Activity activity) {
        Log.i(TAG, "onStop called :: " + activity.getLocalClassName());
        MemoryManager.unregisterMemoryListener(this);
    }

    @Override
    public void onDestroy(Activity activity) {
        Log.i(TAG, "onDestroy called :: " + activity.getLocalClassName());
    }

    @Override
    public void releaseMemory() {
        Log.i(TAG, "releaseMemory() called");
    }

我在调用onTrimMemory()时缺少什么?

3 个答案:

答案 0 :(得分:4)

如果您查看the documentation for ComponentCallbacks2,您会发现它已在ApplicationActivity等类上实施。因此,对于这些组件,欢迎您覆盖onTrimMemory(),并在适当时调用它。

这应该允许您删除问题中的所有代码。

答案 1 :(得分:2)

您不应该实现ComponentCallbacks2,如果要使用onTrimMemory(),则应该在Application类中覆盖onTrimMemory()。但是,如果您真的希望在自定义类中正确使用它,请使用registerComponentCallbacks(ComponentCallbacks callback)

如果您想开始跟踪活动生命周期,可以使用registerActivityLifecycleCallbacks(callback);

回调是实现Application.ActivityLifecycleCallbacks

的Application类

例如,您可以在Application类的OnCreate方法中注册它。

答案 2 :(得分:0)

也许这对于其他人来说是显而易见的,但是对我来说,我浪费了很多时间来弄清楚这个问题:在整个SYSTEM不足的时候调用onTrimMemory,而不是专门针对您的应用程序。嗯,当您的应用程序进入后台以释放UI资源时,也会调用它,但这与本次讨论无关。

您的应用可能会在系统认为自身总体较低之前就耗尽分配给其JVM的内存。

要确定您的应用程序内存是否不足,您需要查看JVM的内存分配。这很简单:

long maxMem = Runtime.getRuntime().maxMemory();
long totalMem = Runtime.getRuntime().totalMemory();
long freeMem = Runtime.getRuntime().freeMemory();
long totalFreeMem = maxMem - totalMem + freeMem;

if (totalFreeMem < (maxMem * 0.2f)) {
    // I'm using 20% as my threshold for "low memory".  Use a value appropriate for your application.
}

totalFreeMem需要该计算,因为totalMemory()只是当前分配给您的JVM的内存总量,它可能小于允许的maxMemory()。 freeMemory()是当前分配的内存中的可用内存量,而不是允许的最大内存量。

不幸的是,这意味着没有自动回调方法可以知道您的JVM何时内存不足(我知道),因此您将需要在代码的各个部分进行内存不足检查,因为您知道内存是定期的被消耗并酌情释放它。

当然,您也可能会遇到系统较低但应用程序的JVM并非如此的情况,因此您仍然希望适当地实现onTrimMemory和可用内存。尽管我认为对于您的JVM来说,拥有足够的内存是一种罕见的情况,但是系统认为总体上来说很低。