美文网首页
android onLowMemory低内存回调方法详解

android onLowMemory低内存回调方法详解

作者: 陈萍儿Candy | 来源:发表于2021-01-17 22:15 被阅读0次

onLowMemory方法顾名思义就是在app内存低的时候回调,那么怎样才是内存低的标准,回调流程又是如何?我们一起带着问题去看源代码解析。
onLowMemory方法在Activity,Servier,ContentProvider,Application中都有回调,但是BroadcastReceiver没有这个回调。

MemBinder是一个Binder类型的服务,主要用于检测系统内存情况;
当系统可用内存比较低的时候就会执行了该方法,然后回调到ActivityManagerService中的killAllBackground方法

可以发现最终通过一个Handler类型的mH成员变量发送一个异步消息,这样异步消息最终会被mH的handleMessage方法执行。。。。,经过查看源代码我们知道在mH的handleMessage方法中最终调用的是handleLowMemory方法

final void handleLowMemory() {
        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);

        final int N = callbacks.size();
        for (int i=0; i<N; i++) {
            callbacks.get(i).onLowMemory();
        }

        // Ask SQLite to free up as much memory as it can, mostly from its page caches.
        if (Process.myUid() != Process.SYSTEM_UID) {
            int sqliteReleased = SQLiteDatabase.releaseMemory();
            EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
        }

        // Ask graphics to free up as much as possible (font/image caches)
        Canvas.freeCaches();

        // Ask text layout engine to free also as much as possible
        Canvas.freeTextLayoutCaches();

        BinderInternal.forceGc("mem");
    }

可以发现这里通过遍历ComponentCallbacks2并执行了其onLowMemory方法,那么这里的ComponentCallBacks2是什么呢?这里我们查看一下collectComponentCallbacks方法的实现逻辑。

ArrayList<ComponentCallbacks2> collectComponentCallbacks(
            boolean allActivities, Configuration newConfig) {
        ArrayList<ComponentCallbacks2> callbacks
                = new ArrayList<ComponentCallbacks2>();

        synchronized (mResourcesManager) {
            final int NAPP = mAllApplications.size();
            for (int i=0; i<NAPP; i++) {
                callbacks.add(mAllApplications.get(i));
            }
            final int NACT = mActivities.size();
            for (int i=0; i<NACT; i++) {
                ActivityClientRecord ar = mActivities.valueAt(i);
                Activity a = ar.activity;
                if (a != null) {
                    Configuration thisConfig = applyConfigCompatMainThread(
                            mCurDefaultDisplayDpi, newConfig,
                            ar.packageInfo.getCompatibilityInfo());
                    if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
                        // If the activity is currently resumed, its configuration
                        // needs to change right now.
                        callbacks.add(a);
                    } else if (thisConfig != null) {
                        // Otherwise, we will tell it about the change
                        // the next time it is resumed or shown.  Note that
                        // the activity manager may, before then, decide the
                        // activity needs to be destroyed to handle its new
                        // configuration.
                        if (DEBUG_CONFIGURATION) {
                            Slog.v(TAG, "Setting activity "
                                    + ar.activityInfo.name + " newConfig=" + thisConfig);
                        }
                        ar.newConfig = thisConfig;
                    }
                }
            }
            final int NSVC = mServices.size();
            for (int i=0; i<NSVC; i++) {
                callbacks.add(mServices.valueAt(i));
            }
        }
        synchronized (mProviderMap) {
            final int NPRV = mLocalProviders.size();
            for (int i=0; i<NPRV; i++) {
                callbacks.add(mLocalProviders.valueAt(i).mLocalProvider);
            }
        }

        return callbacks;
    }

可以发现该方法最终返回类型为ArrayList类型的callBacks而我们的callBacks中保存的是我们应用进程中的Activity,Service,Provider以及Application等。Activity,Service,Provider,Application都是ComponentCallBacks2类型的么?我们看一看一下具体的定义:
Activity的定义:

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2,
        Window.OnWindowDismissedCallback

Service的类定义:

public abstract class Service extends ContextWrapper implements ComponentCallbacks2

ContentProvider的类定义:

public abstract class ContentProvider implements ComponentCallbacks2

Application的类定义:

public class Application extends ContextWrapper implements ComponentCallbacks2

可以发现其都是继承与ComponentCalbacks2,所以其都可以被当做是ComponentCallbacks2类型的变量。而同样是四大组件的BroadcastReceiver,我们可以下其类定义:

public abstract class BroadcastReceiver

可以看到其并未继承与ComponentCallbacks2,所以并未执行,所以通过这样的分析,我们知道了,最终应用程序中的Activity,Servier,ContentProvider,Application的onLowMemory方法会被执行。而由于我们是在系统内存紧张的时候会执行killAllBackground方法进而通过层层条用执行Activity、Service、ContentProvider、Application的onLowMemory方法,所以我们可以在这些组件的onLowMemory方法中执行了一些清理资源的操作,释放一些内存,尽量保证自身的应用进程不被杀死。

总结:

系统在JNI层会时时检测内存变量,当内存过低时会通过kiilbackground的方法清理后台进程。

经过层层的调用过程最终会执行Activity、Service、ContentProvider、Application的onLowMemory方法。

可以在组件的onLowMemory方法中执行一些清理资源的操作,释放内存防止进程被杀死。

参考:https://blog.csdn.net/mhhyoucom/article/details/77982018

相关文章

网友评论

      本文标题:android onLowMemory低内存回调方法详解

      本文链接:https://www.haomeiwen.com/subject/wqennktx.html