ActivityManagerService原理分析

本文详细介绍了Android系统中ActivityManagerService的启动过程及其核心功能,包括四大组件的统一调度、进程管理和内存管理,并通过源码分析揭示其工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.概述

ActivityManagerService是Framework层的核心服务之一,ActivityManagerService是Binder的子类,它的功能主要以下三点:

  • 四大组件的统一调度
  • 进程管理
  • 内存管理

二.ActivityManagerService中的重要变量

  • static final int MAX_ACTIVITYS =20;系统允许的最大后台activity的数目
  • static final int MAX_RECENT_TASK=20; 系统最多存储20个任务栈
  • static final int MAX_HIDDEN_APP=15;系统允许处于hidden状态的进程数目的最大值,超过这个值后,Ams会杀死掉优先级较低的进程
  • ActivityStackSupervisor mStackSupervisor; 通过这个类管理ActivityStacks
  • final ActiveServices mServices; 服务的管理类,管理服务的所有的逻辑
  • final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 前台/后台广播队列
  • private final RecentTasks mRecentTasks; 最近的任务的意图列表
  • final ProcessMap mProcessNames = new ProcessMap(); 当前正在运行的所有进程列表
  • final ArrayList mLruProcesses = new ArrayList();最近使用的进程列表
  • final ArrayList mProcessesToGc = new ArrayList();一旦事情闲置,应该gc的进程列表
  • final HashMap

三.ActivityManagerService的启动过程

ActivityManagerService的启动是在systemserver进程的startBootstrapServices方法中启动的.下面通过源码来分析这个启动过程.
step1.systemserver.startBootstrapServices

private void startBootstrapServices() {
 // Activity manager runs the show.
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
}

这里调用mSystemServiceManager.startService()来帮助处理,不过这里启动的是ActivityManagerService.Lifecycle类

setp2.SystemService startService

 public SystemService startService(String className) {
        final Class<SystemService> serviceClass;
        try {
//通过类加载将类加载进内存
            serviceClass = (Class<SystemService>)Class.forName(className);
        } catch (ClassNotFoundException ex) {
        }
    //调用startService(serviceClass)进一步处理
        return startService(serviceClass);
    }

 public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            final T service;
            try {
            //通过反射创建service
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } 

            // Register it.
            mServices.add(service);

            // Start it.
            try {
             启动service
                service.onStart();
            } catch (RuntimeException ex) {

            }
            return service;
        } 
    }

因为这里启动的是ActivityManagerService.Lifecycle类,调用ActivityManagerService.Lifecycle类的start方法来启动,下面就看看这个类.
step3.ActivityManagerService.Lifecycle

 public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;

        public Lifecycle(Context context) {
            super(context);
这个类创建对象的同时就创建出了ActivityManagerService
            mService = new ActivityManagerService(context);
        }

        @Override
        public void onStart() {
     //启动ActivityManagerService
            mService.start();
        }

        public ActivityManagerService getService() {
            return mService;
        }
    }

从上面的代码可以看出,这个类实际上就是帮我们创建出ActivityManagerService的对象,并且调用start方法开启服务.下面在看看ActivityManagerService在创建的时候做了什么.

step4.ActivityManagerService的构造方法

public ActivityManagerService(Context systemContext) {
        mContext = systemContext;
        mFactoryTest = FactoryTest.getMode();
        mSystemThread = ActivityThread.currentActivityThread();

        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());

        mHandlerThread = new ServiceThread(TAG,
                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
        mHandlerThread.start();
        //创建处理主要逻辑的hander
        mHandler = new MainHandler(mHandlerThread.getLooper());
        //创建处理UI的handler,比如处理无响应的对话框,弹出debug模式的对话框
        mUiHandler = new UiHandler();

        //创建存放前台和后台广播的广播队列
        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
                "foreground", BROADCAST_FG_TIMEOUT, false);
        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
                "background", BROADCAST_BG_TIMEOUT, true);
        mBroadcastQueues[0] = mFgBroadcastQueue;
        mBroadcastQueues[1] = mBgBroadcastQueue;
        //创建管理service的类
        mServices = new ActiveServices(this);
        //创建管理provider的类
        mProviderMap = new ProviderMap(this);

        在ams服务之外创建电池统计服务
        // TODO: Move creation of battery stats service outside of activity manager service.
        //创建system目录
        File dataDir = Environment.getDataDirectory();
        File systemDir = new File(dataDir, "system");
        systemDir.mkdirs();
        //创建电池服务
        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
        mBatteryStatsService.getActiveStatistics().readLocked();
        mBatteryStatsService.scheduleWriteToDisk();
        mOnBattery = DEBUG_POWER ? true
                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
        mBatteryStatsService.getActiveStatistics().setCallback(this);
        //创建跟踪长期执行流程以寻找滥用等糟糕的应用行为的服务
        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
        //创建关于和控制应用程序操作的信息的服务
        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);

        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));

        // User 0 is the first and only user that runs at boot.
        //UserHandle表示一个用户
        mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
        mUserLru.add(UserHandle.USER_OWNER);
        updateStartedUserArrayLocked();

        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);

        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
        //配置信息
        mConfiguration.setToDefaults();
        mConfiguration.setLocale(Locale.getDefault());

        mConfigurationSeq = mConfiguration.seq = 1;
        mProcessCpuTracker.init();

        //用户要求以屏幕尺寸兼容模式运行的软件包
        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);

        //用于启动最近的任务的意图列表
        mRecentTasks = new RecentTasks(this);
        //管理Activity的类,通过这个运行所有的ActivityStack,辅助启动startactivity
        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
        //重新启动时保存最近的任务信息
        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
        //运行时cpu用于收集线程
        mProcessCpuThread = new Thread("CpuTracker") {
            @Override
            public void run() {
                while (true) {
                    try {
                        try {
                            synchronized(this) {
                                final long now = SystemClock.uptimeMillis();
                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
                                //        + ", write delay=" + nextWriteDelay);
                                if (nextWriteDelay < nextCpuDelay) {
                                    nextCpuDelay = nextWriteDelay;
                                }
                                if (nextCpuDelay > 0) {
                                    mProcessCpuMutexFree.set(true);
                                    this.wait(nextCpuDelay);
                                }
                            }
                        } catch (InterruptedException e) {
                        }
                        updateCpuStatsNow();
                    } catch (Exception e) {
                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
                    }
                }
            }
        };
        //获取看门狗对象,并且将当前线程也就是这个服务添加进去
        Watchdog.getInstance().addMonitor(this);
        Watchdog.getInstance().addThread(mHandler);
    }

acitivtymanagerservie的构造函数主要初始化了四大组件的管理类,以及处理主要逻辑的mHandler和处理ui相关的mUiHandler ,比如弹出anr等对话框.

Step5.ActivityManagerService.start()

   private void start() {
//删除所有的进程组,确保刚启动的时候是没有进程的
        Process.removeAllProcessGroups();
     将CPU用来收集线程的线程启动
        mProcessCpuThread.start();
启动电池服务
        mBatteryStatsService.publish(mContext);
启动关于和控制应用程序操作的信息的服务
        mAppOpsService.publish(mContext);
        类似servermanger,只不过这个是用于当前进程
     LocalServices.addService(ActivityManagerInternal.class, new LocalService());
    }

到这一步ActivityManagerService服务就真正的开启了,就会开始真正的执行前面说的3个主要功能了.

四.主要功能之一的四大组件的统一调度

ActivityManagerService最主要的功能就是统一的管理者activity,service,broadcast,provider的创建,运行,关闭.我们在应用程序中启动acitivity,关闭acitiviy等操作最终都是要通过ams来统一管理的.这个过程非常的复杂,不是一下子可以讲的清楚的,我这里推荐老罗的博客来讲解四大组件的启动过程:

五.主要功能之一的内存管理

我们知道当一个进程中的acitiviy全部都关闭以后,这个空进程并不会立即就被杀死.而是要等到系统内存不够时才会杀死.但是实际上ActivityManagerService并不能够管理内存,android的内存管理是Linux内核中的内存管理模块和OOM进程一起管理的.Android进程在运行的时候,会通过Ams把每一个应用程序的oom_adj值告诉OOM进程,这个值的范围在-16-15,值越低说明越重要,越不会被杀死.当发生内存低的时候,Linux内核内存管理模块会通知OOm进程根据AMs提供的优先级强制退出值较高的进程.因此Ams在内存管理中只是扮演着一个提供进程oom_adj值的功能.真正的内存管理还是要调用OOM进程来完成.下面通过调用Activity的finish()方法来看看内存释放的情况.

当我们手动调用finish()方法或者按back键时都是会关闭activity的,,在调用finish的时候只是会先调用ams的finishActivityLocked方法将当前要关闭的acitiviy的finish状态设置为true,然后就会先去启动新的acitiviy,当新的acitiviy启动完成以后就会通过消息机制通知Ams,Ams在调用activityIdleInternalLocked方法来关闭之前的acitiviy.下面就看看activityIdleInternalLocked的源码

ActivityStackSupevis.activityIdleInternalLocked

 final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
            Configuration config) {

//所有要暂停的activity
        ArrayList<ActivityRecord> stops = null;
     //所有要finish的activity
        ArrayList<ActivityRecord> finishes = null;
        ArrayList<UserState> startingUsers = null;
        int NS = 0;
        int NF = 0;
        boolean booting = false;
        boolean activityRemoved = false;


        if (allResumedActivitiesIdle()) {
            if (r != null) {
1.通知所有需要内存回收的进程进行内存回收(这些进程都保存在mProgressToGc列表中)
                mService.scheduleAppGcsLocked();
            }

     2.  分别拿到所有要stop和finish的activity存放在stops和finishs容器中,然后将记录清空
        stops = processStoppingActivitiesLocked(true);
        NS = stops != null ? stops.size() : 0;
        if ((NF = mFinishingActivities.size()) > 0) {
            finishes = new ArrayList<>(mFinishingActivities);
            mFinishingActivities.clear();
        }

        if (mStartingUsers.size() > 0) {
            startingUsers = new ArrayList<>(mStartingUsers);
            mStartingUsers.clear();
        }

      3. 停止stops中的所有activity
        for (int i = 0; i < NS; i++) {
            r = stops.get(i);
            final ActivityStack stack = r.task.stack;
            if (stack != null) {
                if (r.finishing) {
                    stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
                } else {
                    stack.stopActivityLocked(r);
                }
            }
        }

       4. 销毁finishs中的所有activity
        for (int i = 0; i < NF; i++) {
            r = finishes.get(i);
            final ActivityStack stack = r.task.stack;
            if (stack != null) {
                activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
            }
        }

     5.该步骤内部真正地进行内存回收工作,包括杀死不必要的进程
mService.trimApplications();
        return r;
    }

在这个方法中除了第一步通知客户进程调用GC来主动回收内存以外,剩下的步骤都是没有操作到内存的,所以说stop或者destroy的回调方法调用的时候只是一个状态的变化,而没有真正意义的对内存进行实质性的停止或者销毁.但是会调用trimApplications方法来进一步操作.

ActivityManagerService.trimApplications

final void trimApplications() {
        synchronized (this) {
            int i;
            首先删除mRemoveProcess列表中包含的进程.这里一般包含的是crash后的进程,弹出ANR的进程,调用KillBackGroundProgress()方法杀死的进程.也就是说crash或者弹出Anr对话框我们点确定的时候系统并不会立马就将这些进程杀死,而是要等空闲时调用activityIdleInternalLocked方法时才会真正的来杀死.
                for (i=mRemovedProcesses.size()-1; i>=0; i--) {
                final ProcessRecord app = mRemovedProcesses.get(i);
                if (app.activities.size() == 0
                        && app.curReceiver == null && app.services.size() == 0) {

                    if (app.pid > 0 && app.pid != MY_PID) {
  不杀死当前进程
                        app.kill("empty", false);
                    } else {
                        try {
                            app.thread.scheduleExit();
                        } catch (Exception e) {
                            // Ignore exceptions.
                        }
                    }
                    cleanUpApplicationRecordLocked(app, false, true, -1);
将杀死的进程,移除
                    mRemovedProcesses.remove(i);

                    if (app.persistent) {
                        addAppLocked(app.info, false, null /* ABI override */);
                    }
                }
            }

            // Now update the oom adj for all processes.
告诉OOM Killer所有进程的优先级
            updateOomAdjLocked();
        }
    }

通过上面的源码知道,我们调用finish方法时关闭一个acitiviy的时候并不会真正的在内存中销毁它,而只是会调用onDestroy方法而已.除了会杀死mRemoveProcess列表中的进程,另外也就只会告诉OOM Killer所有进程的优先级.并不会主动的去杀死其他进程.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值