【Android-AMS】ActivityManagerService启动分析

(Android 8.1)

本文参考了邓平凡的《深入理解Android 卷2》第6章 “深入理解ActivityManangerService。该书虽然有点老,2012年出版,但仍然是Android源码分析的经典,即使是到了2020年的现在,如果你想深入解理Android,它仍然是一个很好选择。由于Android版本的升级,部分代码有些变化,但这不影响你对整体构架的理解。本文就是阅读该书时对照Android8.1源码整理出来的。

------------------------------------------------------------------------------------------------------------------------------------

相关文件:

frameworks\base\services\java\com\android\server\SystemServer.java

frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java

frameworks\base\services\core\java\com\android\server\am\ActivityStack.java

frameworks\base\services\core\java\com\android\server\am\ActivityStackSupervisor.java

frameworks\base\services\core\java\com\android\server\am\ActivityStarter.java

frameworks\base\services\core\java\com\android\server\am\ActiveServices.java

frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java

frameworks\base\core\java\android\app\ActivityThread.java

frameworks\base\core\java\android\app\ContextImpl.java

frameworks\base\core\java\android\app\LoadedApk.java

ActivityManagerService(后面简称AMS)的启动:

  • 1.系统启动入口

【SystemServer.java.ava::run】

 private void run() {
        try {
            //省略部分代码
            //HHHA:1====>Initialize the system context.
            createSystemContext();
            //省略部分代码
        } finally {
            traceEnd();  // InitBeforeStartServices
        }

        // Start services.
        try {
            traceBeginAndSlog("StartServices");
            //HHHA:2====>启动boot阶段服务
            startBootstrapServices();
            //HHHA:3====>启动核心服务
            startCoreServices();
            //HHHA:4====>启动其它服务
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            
        //省略部分代码
    }

    HHHA:1====>是运行环境进行初始化

    HHHA:2====>AMS在此创建

    HHHA:4====>设置AMS的一些外部环境

先来看HHHA:1====>展开如下:

1.1 createSystemContext分析

【SystemServer.java.java::createSystemContext】

    private void createSystemContext() {
        //HHHB:1====>创建ActivityThread类
        ActivityThread activityThread = ActivityThread.systemMain();
        //HHHB:2====>获取系统运行环境,并设置主题
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
        //HHHB:3====>获取系统UI环境,并设置主题为默认
        final Context systemUiContext = activityThread.getSystemUiContext();
        systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
    }
  • 1.1.2. ActivityThread.systemMain函数分析

ActivityThread是Android Framework中一个非常重要的类,它代表一个应用进行的主线程(对于应用进程来说,ActivityThread的main函数确实是由该进行的主纯种执行),其职责就是调度及执行在该线程中运行的四大组件。

【ActivityThread.java::systemMain】

    public static ActivityThread systemMain() {
        // The system process on low-memory devices do not get to use hardware
        // accelerated drawing, since this can add too much overhead to the
        // process.
        if (!ActivityManager.isHighEndGfx()) {
            ThreadedRenderer.disable(true);  //禁止硬件渲染加速
        } else {
            ThreadedRenderer.enableForegroundTrimming();
        }
        ActivityThread thread = new ActivityThread();  //p1:创建一个新线程
        thread.attach(true);  //p2:调用它的attach函数,传递的参数为true
        return thread;
    }

p2展开

【ActivityThread.java::attach】

private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            ……//应用进行的处理流程
            
        } else {
            // Don't set application object here -- if the system crashes,
            // we can't display an alert, we just want to die die die.
            android.ddm.DdmHandleAppName.setAppName("system_process",
                    UserHandle.myUserId());
            try {
                //ActivityThread的几员“大将”出场,见后文分析
                mInstrumentation = new Instrumentation();
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                mInitialApplication.onCreate();  //调用Application的onCreate回调
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
            }
        }

        // add dropbox logging to libcore
        DropBox.setReporter(new DropBoxReporter());

        ViewRootImpl.ConfigChangedCallback configChangedCallback
                = (Configuration globalConfig) -> {
                ……//当系统配置发生变化(如语言切换等)时,需要调用该回调
            }
        };
        ViewRootImpl.addConfigCallback(configChangedCallback);
    }

attach函数中出现了几个的重要成员:

    Instrumentation mInstrumentation;  //用于创建其他组件,系统与组件之间交互

    private ContextImpl mSystemContext;    //系统上下文

    private ContextImpl mSystemUiContext;  //UI上下文

    Application mInitialApplication;  //初始化app,也就是system_server自己

可见不止一种Context,系统上下文和UI上下文是分开管理的,这些Context是在ContextImpl中实现的

ContextImpl中提供了几个相关的接口:

static ContextImpl createSystemContext(ActivityThread mainThread)

static ContextImpl createSystemUiContext(ContextImpl systemContext) 

static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo)

static ContextImpl createActivityContext(ActivityThread mainThread, ...) 

attach中虽然调用了ContextImpl.createAppContext,但并没用保存它,而是通过它来创建一个Application,然后调用这个application的onCreate回调。

而ActivityThead中只保存了SystemContext和SystemUiContext两种,相应的访问接口:

【ContextImpl.java】

    public ContextImpl getSystemContext() {
        synchronized (this) {
            if (mSystemContext == null) {
                mSystemContext = ContextImpl.createSystemContext(this);
            }
            return mSystemContext;
        }
    }

    public ContextImpl getSystemUiContext() {
        synchronized (this) {
            if (mSystemUiContext == null) {
                mSystemUiContext = ContextImpl.createSystemUiContext(getSystemContext());
            }
            return mSystemUiContext;
        }
    }

这两个接口的工作方式一模一样:如果已经创建,直接返回该成员,否则调用ContextImpl的createXXXContext()创建一新对象。

1.1.3 contextImpl的createSystemContext等

再看一眼ContextImpl中的几个createXXXContext()的工作方式,也是类似的:都是先new一个ContextImpl然后用setResources来设置其资源,主要区别是参数不同:

【ContextImpl.java】

 static ContextImpl createSystemContext(ActivityThread mainThread) {
        LoadedApk packageInfo = new LoadedApk(mainThread);
        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
                null);
        context.setResources(packageInfo.getResources());
        context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                context.mResourcesManager.getDisplayMetrics());
        return context;
    }

    /**
     * System Context to be used for UI. This Context has resources that can be themed.
     * Make sure that the created system UI context shares the same LoadedApk as the system context.
     */
    static ContextImpl createSystemUiContext(ContextImpl systemContext) {
        final LoadedApk packageInfo = systemContext.mPackageInfo;
        ContextImpl context = new ContextImpl(null, systemContext.mMainThread, packageInfo, null,
                null, null, 0, null);
        context.setResources(createResources(null, packageInfo, null, Display.DEFAULT_DISPLAY, null,
                packageInfo.getCompatibilityInfo()));
        return context;
    }

    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
                null);
        context.setResources(packageInfo.getResources());
        return context;
    }

    static ContextImpl createActivityContext(ActivityThread mainThread,
            LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId,
            Configuration overrideConfiguration) {
        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");

        ……

        return context;
    }

1.1.4 Context是什么?

    顾名思义,它代表运行环境。它是一个接口,通过它可以获取并操作Application对应的资源、类,甚至包含于Application中的四大组件。

  既然是接口,那么它的实现在哪呢?答案是ContextImpl。

【ContextImpl.java】

class ContextImpl extends Context {
    ……
}

Context的创建、相关资源的访问都是在这个类中实现的,如上面所提到的createSystemContext()等,此外还有createResources()、setResources()、getApplicationInfo()等。这些接口主要实现下列各种操作:

  • 资源的增删改    
  •  Activity的启动
  • 广播的注册、发送
  • 服务的启动、停止
  • 权限的检测
  • 其它

下面列举一些比较有代表性的接口实现:

【ContextImpl.java】

//资源相关

void setResources(Resources r) 

public Resources getResources()

public ApplicationInfo getApplicationInfo()

//各种Context

static ContextImpl createSystemContext(ActivityThread mainThread)

static ContextImpl createSystemUiContext(ContextImpl systemContext)

static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) 

static ContextImpl createActivityContext(ActivityThread mainThread, ...)

public Context createDisplayContext(Display display)

//Activity相关

public void startActivity(Intent intent) 

public void startActivity(Intent intent, Bundle options)

public void startActivityAsUser(Intent intent, Bundle options, UserHandle user)

//broadcast相关

public void sendBroadcast(Intent intent)

public void sendOrderedBroadcast(Intent intent, String receiverPermission)

public void sendStickyBroadcast(Intent intent)

public void sendBroadcastAsUser(Intent intent, UserHandle user)

public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter)

//service相关

public ComponentName startService(Intent service)

public boolean stopService(Intent service)

public boolean bindService(Intent service, ServiceConnection conn, int flags) 

//权限相关

public int checkPermission(String permission, int pid, int uid) 

public void enforcePermission(String permission, ...)

阅读这个文件时,只要知道它实现了什么接口即可,等需要分析具体的逻辑的时候再点开具体的函数进行逐行分析。这就要从宏观轻松掌握这个文件的框架,就像拎起一串葡萄一样。

1.2 startBootstrapServices()分析

先回顾一下最开始的入口函数

【SystemServer.java::run()】

private void run() {
        try {
            //省略部分代码
            //HHHA:1====>Initialize the system context.
            createSystemContext();
            //省略部分代码
        } finally {
            traceEnd();  // InitBeforeStartServices
        }

        // Start services.
        try {
            traceBeginAndSlog("StartServices");
            //HHHA:2====>启动boot阶段服务
            startBootstrapServices();
            //HHHA:3====>启动核心服务
            startCoreServices();
            //HHHA:4====>启动其它服务
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            
        //省略部分代码
    }

现在是把HHHA:2====>展开,并省略与AMS无关的部分:

【SystemServer.java::startBootstrapServices】

private void startBootstrapServices() {
        ……
        // Activity manager runs the show.
        traceBeginAndSlog("StartActivityManager");
        // HHHC:1====>创建并启动AMS
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        //HHHC:2====>设置SSM
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        //HHHC:3====>设置installer
        mActivityManagerService.setInstaller(installer);
        traceEnd();

        ……

        // Now that the power manager has been started, let the activity manager
        // initialize power management features.
        traceBeginAndSlog("InitPowerManagement");
        //HHHC:4====>初始化与电源相关的状态等
        mActivityManagerService.initPowerManagement();
        traceEnd();
        
        ……

        // Set up the Application instance for the system process and get started.
        traceBeginAndSlog("SetSystemProcess");
        //HHHC:5====>为framework-res.apk设置一些特殊标识
        mActivityManagerService.setSystemProcess();
        traceEnd();
        ……
    }

HHHC:1====>要点:

    1.获取ActivityManagerService.Lifecycle这个静态内部类;

    2.启动AMS:(startService的时候将触发Lifecycle.onStart()被调用);

    3.mActivityManager得到的是AMS服务的一个Bn句柄;

简单看下ActivityManagerService这个类: 

【ActivityManagerService.java::ActtivityManagerService】

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    ……

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

        public Lifecycle(Context context) {
            super(context);
            mService = new ActivityManagerService(context);
        }

        @Override
        public void onStart() {
            mService.start();
        }

        @Override
        public void onCleanupUser(int userId) {
            mService.mBatteryStatsService.onCleanupUser(userId);
        }

        public ActivityManagerService getService() {
            return mService;
        }

    ……
}

    a)它继承了IActivityManager.stub

    b)通过静态内部类的来实现了单例

    c)是Lifecycle继承了SystemService,而不是ActivityManagerService

1.2.1 ActivityManagerService的构造函数

  1.1是创建运行环境,而真正与AMS直接相关的是现在才开始。《深入理解Android卷2》中,createSystemContext()是在AMS中完成的,其逻辑比较复杂。可见是随着Android版本的升级,代码进行了优化。最大的区别是把createSystemContext提到了最外层函数来,这样安排后代码结构明显变得更加清晰。

a) ActivityManagerService构造函数分析1

【ActivityManagerService.java::ActivityManagerService】

public ActivityManagerService(Context systemContext) {
        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
        mInjector = new Injector();
        //HHHD:1====>设置Context
        mContext = systemContext;

        mFactoryTest = FactoryTest.getMode();
        //HHHD:2====>获取System线程
        mSystemThread = ActivityThread.currentActivityThread();
        mUiContext = mSystemThread.getSystemUiContext();

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

        mPermissionReviewRequired = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_permissionReviewRequired);
        //HHHD:3====>创建并启动消息处理线程
        mHandlerThread = new ServiceThread(TAG,
                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
        mHandlerThread.start();
        //HHHD:4====>创建MainHandler
        mHandler = new MainHandler(mHandlerThread.getLooper());
        //HHHD:5====>获取UiHandler
        mUiHandler = mInjector.getUiHandler(this);

        mConstants = new ActivityManagerConstants(this, mHandler);
        //HHHD:6====>创建“刽子手”
        /* static; one-time init here */
        if (sKillHandler == null) {
            sKillThread = new ServiceThread(TAG + ":kill",
                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
            sKillThread.start();
            sKillHandler = new KillHandler(sKillThread.getLooper());
        }

既然是构造函数,其主要任务自然是初始化一些关键变量,其中包括设置Context,获得主线程,创建消息处理线程等等。

HHHD:2====>展开:

【ActivityThread.java::currentActivityThread】

private static volatile ActivityThread sCurrentActivityThread;

public static ActivityThread currentActivityThread() {
    return sCurrentActivityThread;
}

public static boolean isSystem() {
    return (sCurrentActivityThread != null) ? sCurrentActivityThread.mSystemThread : false;
}

private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
}    

要点:

  • currentActivityThread()获取的是ActivityThread的一个静态实例
  • 这个静态实例代表当前活动的Activity的处理线程
  • 这个静态实例在attach接口调用时设置
  • 用mSystemThread来标识是系统还是其它应用

回顾1.1.2 ActivityThread.java::systemMain中调用attach时所传的参数是true。其实也就只有这一个地方的调用会传true,由前面的分析可知它的外层调用函数是createSystemContext(),然后更外层是SystemServer.java::run()。SystemServer本身也是一个应用,由于它的特殊性,这里用了mSystemThread来专门标识,方便后面一些逻辑处理有别于普通的应用,通俗地讲是让SystemServer成为VIP应用,在有调用一些接口时有某种“特权”。如果你在代码中搜索mSystemThread就可以找到到底哪些接口的逻辑是有区别对代的。

//HHHD:3====>展开:

【ServiceThread.java::ServiceThread】

public class ServiceThread extends HandlerThread {
    private static final String TAG = "ServiceThread";

    private final boolean mAllowIo;

    public ServiceThread(String name, int priority, boolean allowIo) {
        super(name, priority);
        mAllowIo = allowIo;
    }

    @Override
    public void run() {
        Process.setCanSelfBackground(false);

        // For debug builds, log event loop stalls to dropbox for analysis.
        if (!mAllowIo && StrictMode.conditionallyEnableDebugLogging()) {
            Slog.i(TAG, "Enabled StrictMode logging for " + getName() + " looper.");
        }

        super.run();
    }
}

它继承了HandlerThread,而HandlerThread又继承了Thread。

Thread是一个单纯的线程,可以理解为它具备做事情的能力,但是具体要做什么它并不清楚。HandlerThread则封装了一个Looper在里面,当这个线程运行的是时候就从这个Looper中loop()函数。而Looper是什么东西呢?它是一个轮寻机制,核心的的东西是消息队列MessageQueue mQueue,当它开始轮巡的时候就尝试从这个队列中取出消息来处理。经过这一系列封装后的效果是:有什么事情要做就只管往这个队列中放,背后的Thread会默默地帮你完成。

    一个HandlerThread通常可以跟多个Handler配对——一夫多妻制,Handler负责定义具体的消息怎么处理,HandlerThread负责分发消息——把mQueue中的消息送到Handler的手上,最终调用Handler.handlerMessage()。因此通常是在Handler的子类中重载handlerMessage(),然后在里面实现具体处理逻辑。比如下面的MainHandler展开:

HHHD:4====>展开

【ActivityManagerService.java::MainHandler】

final class MainHandler extends Handler {
        public MainHandler(Looper looper) {
            super(looper, null, true);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case UPDATE_CONFIGURATION_MSG: {
                final ContentResolver resolver = mContext.getContentResolver();
                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
                        msg.arg1);
            } break;
            case GC_BACKGROUND_PROCESSES_MSG: {
                synchronized (ActivityManagerService.this) {
                    performAppGcsIfAppropriateLocked();
                }
            } break;
            case SERVICE_TIMEOUT_MSG: {
       ……
}

其中构造函数传入的Looper就是HHHD:3====>展开中所描述的封装在HanderThread中的Looper。

HHHD:5====>

mUiHandler = mInjector.getUiHandler(this);

其本质跟HHHD:3====> 加上 HHHD:4====>所做的事情一样:

  • 获得一个Handler
  • 获得一个HandlerThread
  • 绑定它们

【ActivityManagerService.java::getUiHandler】

public Handler getUiHandler(ActivityManagerService service) {
    return service.new UiHandler();
}

final class UiHandler extends Handler {
    public UiHandler() {
        super(com.android.server.UiThread.get().getLooper(), null, true);
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case SHOW_ERROR_UI_MSG: {
            mAppErrors.handleShowAppErrorUi(msg);
            ensureBootCompleted();
        } break;
    ……
}

其中充当Handler角色的它的子类UiHandler,而HandlerThread则通过com.android.server.UiThread.get().getLooper()获得,把UiThread展开看看:

【UiThread.java::UiThread】

public final class UiThread extends ServiceThread {
    private static UiThread sInstance;
    private static Handler sHandler;
    private UiThread() {
        super("android.ui", Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
    }

    @Override
    public void run() {
        // Make sure UiThread is in the fg stune boost group
        Process.setThreadGroup(Process.myTid(), Process.THREAD_GROUP_TOP_APP);
        super.run();
    }

    ……

    public static UiThread get() {
        synchronized (UiThread.class) {
            ensureThreadLocked();
            return sInstance;
        }
    }

    ……
}

原来它是ServiceThread的子类,其特别之处是多了两个静态成员:sInstance和sHandler,这是通过静态成员来实现单例。由此可知,android系统中自始至终只有一个UI线程。

HHHD:6====>

还是用Handler-HandlerThread机制,HandlerThread用的是ServiceThread,前面已经说过了。现在展开KillHandler看一眼

【ActivityManagerService.java::KellHandler】

final class KillHandler extends Handler {
        static final int KILL_PROCESS_GROUP_MSG = 4000;

        public KillHandler(Looper looper) {
            super(looper, null, true);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case KILL_PROCESS_GROUP_MSG:
                {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                }
                break;

                default:
                    super.handleMessage(msg);
            }
        }
    }

发现它只处理KILL_PROCESS_GROUP_MSG这一种消息:调用Process.killProcessGroup(uid,pid)来杀死指定的进程。

ActivityManagerService构造函数分析1总结:

  • 初始化Context
  • 初始化mSystemThread
  • 初始化三个Handler: mHandler、mUiHandler、sKillThreadler

b) ActivityManagerService构造函数分析2

        //HHHD:7====>初始化几个广播队列
        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;

        //HHHD:8====>创建ActivieServices, 注意变量名是mServices
        mServices = new ActiveServices(this);
        //HHHD:9====>创建ProviderMap
        mProviderMap = new ProviderMap(this);
        mAppErrors = new AppErrors(mUiContext, this);

        //HHHD:10====>创建/data/system/目录
        // TODO: Move creation of battery stats service outside of activity manager service.
        File dataDir = Environment.getDataDirectory();
        File systemDir = new File(dataDir, "system");
        systemDir.mkdirs();
        //HHHD:11====>创建电量统计服务,并调取电量统计等信息
        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
        mBatteryStatsService.getActiveStatistics().readLocked();
        mBatteryStatsService.scheduleWriteToDisk();
        mOnBattery = DEBUG_POWER ? true
                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
        mBatteryStatsService.getActiveStatistics().setCallback(this);
        //HHHD:12====>创建内存统计服务
        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
        //HHHD:13====>创建App行为服务
        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
                new IAppOpsCallback.Stub() {
                    @Override public void opChanged(int op, int uid, String packageName) {
                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
                            if (mAppOpsService.checkOperation(op, uid, packageName)
                                    != AppOpsManager.MODE_ALLOWED) {
                                runInBackgroundDisabled(uid);
                            }
                        }
                    }
                });
        //HHHD:14====>创建授权文件
        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
        //HHHD:15====>用户控制器
        mUserController = new UserController(this);
        //HHHD:16====>VR控制器
        mVrController = new VrController(this);

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

        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
            mUseFifoUiScheduling = true;
        }

HHHD:8====>分析:
mServices = new ActiveServices(this);

这个ActiveService.java把跟“服务”相关性比较大的代码封装起来,本来是可以直接放在ActivityManagerService.java下的,但是这会是使个文件又臭又长,其实已经够臭够长了——有2万多行!把一些相关性比较强的逻辑独立成一个文件通常会使框架更加清晰。当然,AMS也还保留有接口,因为那是服务的入口,而ActivityService.java封装了跟服务相关的真正实现。我们来看下它的一些接口:

int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,...)

void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service)

boolean unbindServiceLocked(IServiceConnection connection) 

private final ServiceRecord findServiceLocked(ComponentName name,...)

private ServiceLookupResult retrieveServiceLocked(Intent service,...)

private final boolean scheduleServiceRestartLocked(ServiceRecord r, boolean allowCancel)

private final void realStartServiceLocked(ServiceRecord r, ...)

final void killServicesLocked(ProcessRecord app, boolean allowRestart) 

void serviceTimeout(ProcessRecord proc)

private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,...)
……

一句话:都是跟服务相关。哎?前面在介绍ContextImpl的时候不是也封装了一些服务相关的接口吗?回顾一下1.1.4的相关内容,并把startService展开看看:

【ContextImpl.java::startService】

public ComponentName startService(Intent service) {
    warnIfCallingFromSystemProcess();
    return startServiceCommon(service, false, mUser);
}

private ComponentName startServiceCommon(Intent service, boolean requireForeground,
            UserHandle user) {
        try {
            validateServiceIntent(service);
            service.prepareToLeaveProcess(this);
            //P1:ActivityManager.getService()将获得AMS的句柄,
            //然后.startService即是调用ActivityManagerService.startService
            ComponentName cn = ActivityManager.getService().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), requireForeground,
                            getOpPackageName(), user.getIdentifier());
            if (cn != null) {
                ……
            }
            return cn;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

我们在把ActivityManagerService.java::startService展开:

【ActivityManagerService.java::startService】

 @Override
    public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, boolean requireForeground, String callingPackage, int userId)
            throws TransactionTooLargeException {
        ……
        synchronized(this) {
            final int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            ComponentName res;
            try {
                //P2:调用ActiveService的startServiceLocked
                res = mServices.startServiceLocked(caller, service,
                        resolvedType, callingPid, callingUid,
                        requireForeground, callingPackage, userId);
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
            ……
        }
    }

P2中的mServices即是HHHD:8====>中的mServices,由此可清晰看到其调用关系是:

ContextImple.java::startService()

     ActivityManagerService.java::startService()

          ActiveService.java::startServiceLocked()

HHHD:8====>总结:

  • 创建了ActiveService实例
  • ActiveService封装了服务相关真正实现

HHHD:10====>分析:

  • TODO:把电量统计服务的创建移到AMS外面,可能是谷歌的工程师认为电量统计服务与AMS耦合性不是特别大,因此考虑把它的创建工作移到AMS外面去会更加合适。
  • 在data中创建了system目录,这是为后面的电量统计作准备的,用adb进入android手机,可以看到/data/system下与电量统计相关的文件:

HHHD:11====>分析:

mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);

在Android手机的 设置/电池 中之所以可以看到每个应用对电池的使用情况,就是因为有这个服务的存在。

看一眼BatteryStatsService:

【BatteryStatsService.java::BatteryStatsService】

public final class BatteryStatsService extends IBatteryStats.Stub
        implements PowerManagerInternal.LowPowerModeListener,
        BatteryStatsImpl.PlatformIdleStateCallback {
    static final String TAG = "BatteryStatsService";
    static final boolean DBG = false;

    private static IBatteryStats sService;

    //P1:核心成员
    final BatteryStatsImpl mStats; 

   //P2:接口举例
   public void noteJobStart(String name, int uid) {
        enforceCallingPermission();
        synchronized (mStats) {
            //P2.1:调用BatterStatsImpl.noteJobStartLocked()
            mStats.noteJobStartLocked(name, uid);
        }
    }
    //P3: 其它各种noteXXXX接口
    public void noteJobFinish(String name, int uid, int stopReason) {...}
    public void noteAlarmStart(String name, int uid){...}
    public void noteAlarmFinish(String name, int uid){...}
    public void noteVibratorOn(int uid, long durationMillis){...}
    public void noteVibratorOff(int uid){...}
    public void noteScreenState(int state){...}
    public void noteScreenBrightness(int brightness){...}
    public void noteUserActivity(int uid, int event){...}
    public void noteWakeUp(String reason, int reasonUid){...}
    public void noteStartAudio(int uid){...}
    public void noteStopAudio(int uid){...}
    public void noteWifiRunning(WorkSource ws){...}
    public void noteWifiStopped(WorkSource ws){...}
    public void noteWifiState(int wifiState, String accessPoint){...}
    ……
}
  • BatteryService.java只是封装了接口
  • 真正的实现是在BatteryStatsImpl.java中(比较Context.java与ContextImpl.java的关系)
  • BatteryStatsImpl.java大部分接口与BatteryService.java同名的函数

在此不打算对BatteryStatsImpl进行深入分析。

c) ActivityManagerService构造函数分析3

【ActivityManagerService.java::ActivityManagerService】

mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
        mTempConfig.setToDefaults();
        mTempConfig.setLocales(LocaleList.getDefault());
        mConfigurationSeq = mTempConfig.seq = 1;
        //HHHD:17====>监视器,新增,《深入理解Android卷2》中没有提到这个烦劳
        mStackSupervisor = createStackSupervisor();
        mStackSupervisor.onConfigurationChanged(mTempConfig);
        //HHHD:18====>按键控制器
        mKeyguardController = mStackSupervisor.mKeyguardController;
        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
        //HHHD:19====>Intent防火墙
        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
        mTaskChangeNotificationController =
                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
        //HHHD:20====>Activity启动器,新增,《深入理解Android卷2》中没有提到这个烦劳
        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
        mRecentTasks = new RecentTasks(this, mStackSupervisor);
        //HHHD:21====>CPU线程:为ANR收集CPU的使用情况
        mProcessCpuThread = new Thread("CpuTracker") {
            @Override
            public void run() {
                synchronized (mProcessCpuTracker) {
                    mProcessCpuInitLatch.countDown();
                    mProcessCpuTracker.init();
                }
                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);
                    }
                }
            }
        };
        //HHHD:22====>关联看门狗
        Watchdog.getInstance().addMonitor(this);
        Watchdog.getInstance().addThread(mHandler);
    }

1.2.2 setSystemServiceManager

//HHHC:2====>设置SSM

mActivityManagerService.setSystemServiceManager(mSystemServiceManager);

【ActivityManagerService.java::setSystemServiceManager】

    public void setSystemServiceManager(SystemServiceManager mgr) {
        mSystemServiceManager = mgr;
    }

有点失望吧,只设置了一个变量,但这个变量还是有点用的,看看它提供了什么接口吧:

【SystemServiceManager.java】

public class SystemServiceManager {

……
//启动其它服务
public SystemService startService(String className) {...}
//boot阶段,协助SystemServer启动
public void startBootPhase(final int phase){...}
//是否启动完成
public boolean isBootCompleted(){...}
//用户启动相关:
public void startUser(final int userHandle){...}

public void unlockUser(final int userHandle){...}

public void switchUser(final int userHandle){...}

public void stopUser(final int userHandle) {...}
//安全模式
void setSafeMode(boolean safeMode){...}

public boolean isSafeMode(){...}
//Runtime是否已重启
public boolean isRuntimeRestarted(){...}

void setRuntimeRestarted(boolean runtimeRestarted){...}

……

}

1.2.3 setInstaller

//HHHC:3====>设置installer
mActivityManagerService.setInstaller(installer);

【ActivityManagerService.java::setInstaller】

    public void setInstaller(Installer installer) {
        mInstaller = installer;
    }

也是设置了一个变量,这是apk安装器的句柄,看看提供了什么接口:

public class Installer extends SystemService {
    ……
    //安装,此处可以推测参数很可能是前面说过的用ContextImpl.java::createApplicationContext()
    //所创建的Context
    public Installer(Context context){...}
    public Installer(Context context, boolean isolated){...}
    private boolean checkBeforeRemote(){...}
    //创建App的数据
    public long createAppData(String uuid, String packageName, int userId,..){...}
    //恢复App数据
    public void restoreconAppData(String uuid, String packageName, int userId,...){...}
    //合并App数据
    public void migrateAppData(String uuid, String packageName, int userId, ...){...}
    //清除App数据
    public void clearAppData(String uuid, String packageName, int userId, ...){...}
    //销毁App数据
    public void destroyAppData(String uuid, String packageName, int userId, ...){...}
    //获得App的大小
    public void getAppSize(String uuid, String[] packageNames, int userId,...){...}
    public void getUserSize(String uuid, int userId, int flags, ...){...}
    //清除App概要
    public void clearAppProfiles(String packageName) {...}
    //销毁App概要
    public void destroyAppProfiles(String packageName){...}
    //创建用户数据
    public void createUserData(String uuid, int userId, int userSerial, int flags){...}
    //销毁用户数据
    public void destroyUserData(String uuid, int userId, int flags){...}
    //标识已经启动完成
    public void markBootComplete(String instructionSet){...}
    //释放缓存
    public void freeCache(String uuid, long targetFreeBytes,  ...){...}
    ……
}

1.2.4 initPowerManagement

//HHHC:4====>初始化与电源相关的状态等
mActivityManagerService.initPowerManagement();

【ActivityManagerService.java::initPowerManagement】

    public void initPowerManagement() {
        mStackSupervisor.initPowerManagement();
        mBatteryStatsService.initPowerManagement();
        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
        //获得PM句柄
        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
        //创建唤醒锁
        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
        mVoiceWakeLock.setReferenceCounted(false);
    }

关于唤醒锁WakeLock和PowerManager的一般操作步骤

  1. PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);通过 Context.getSystemService().方法获取PowerManager实例。
  2. 然后通过PowerManager的newWakeLock((int flags, String tag)来生成WakeLock实例。int Flags指示要获取哪种WakeLock,不同的Lock对cpu 、屏幕、键盘灯有不同影响。
  3. 获取WakeLock实例后通过acquire()获取相应的锁,然后进行其他业务逻辑的操作,最后使用release()释放(释放是必须的)。

关于int flags

  各种锁的类型对CPU 、屏幕、键盘的影响:

    PARTIAL_WAKE_LOCK: 保持CPU 运转,屏幕和键盘灯有可能是关闭的。

    SCREEN_DIM_WAKE_LOCK:保持CPU 运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯

    SCREEN_BRIGHT_WAKE_LOCK:保持CPU 运转,允许保持屏幕高亮显示,允许关闭键盘灯

    FULL_WAKE_LOCK:保持CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度

    ACQUIRE_CAUSES_WAKEUP:正常唤醒锁实际上并不打开照明。相反,一旦打开他们会一直仍然保持(例如来世user的activity)。当获得wakelock,这个标志会使屏幕或/和键盘立即打开。一个典型的使用就是可以立即看到那些对用户重要的通知。

    ON_AFTER_RELEASE:设置了这个标志,当wakelock释放时用户activity计时器会被重置,导致照明持续一段时间。如果你在wacklock条件中循环,这个可以用来减少闪烁

1.2.5 setSystemProcess

//HHHC:5====>

mActivityManagerService.setSystemProcess();

【ActivityManagerService.java::setSystemProcess】

public void setSystemProcess() {
        try {
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
            //添加应用内存使用情况服务
            ServiceManager.addService("meminfo", new MemBinder(this));
            //添加图形硬件使用情况服务
            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
            
            ServiceManager.addService("dbinfo", new DbBinder(this));
            if (MONITOR_CPU_USAGE) {
                //添加CPU相关信息服务
                ServiceManager.addService("cpuinfo", new CpuBinder(this));
            }
            //添加权限控制服务
            ServiceManager.addService("permission", new PermissionController(this));
            ServiceManager.addService("processinfo", new ProcessInfoService(this));

            
            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
            //HHHE:1====>调用ActivityThread的installSystemApplicationInfo函数
            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());

            synchronized (this) {
                //HHHE:2====> 此处涉及AMS对进程的管理,见下文分析
                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
                //“android"作为一个特殊的应用,设置它专用的属性
                app.persistent = true;
                app.pid = MY_PID;
                app.maxAdj = ProcessList.SYSTEM_ADJ;
                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
                synchronized (mPidsSelfLocked) {
                    //HHHE:3====> 保存该ProcessRecord对象
                    mPidsSelfLocked.put(app.pid, app);
                }
                //根据系统当前状态,调整进程的高度优先级和OOM_ADJ
                updateLruProcessLocked(app, false, null);
                updateOomAdjLocked();
            }
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(
                    "Unable to find android system package", e);
        }
    }

HHHE:1====>

【ActivityThread.java::installSystemApplicationInfo】

    public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
        synchronized (this) {
            //把当前应用("android")的信息分别保存到mSystemContext和mSystemUIContext中
            getSystemContext().installSystemApplicationInfo(info, classLoader);
            getSystemUiContext().installSystemApplicationInfo(info, classLoader);

            // give ourselves a default profiler
            //创建一个Profiler对象,用于性能统计
            mProfiler = new Profiler();
        }
    }

HHHE:2====>

ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);

ProcessRecord是什么?

ProcessRecord用于封装进程有关的信息,每个应用对应一个ProcessRecord,AMS把这些record放在变量mPidsSelfLocked中管理。

【ActivityManagerService.java】

final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();

HHHE:2===>展开:

【ActivityManagerService.java::newProcessRecordLocked】

final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
            boolean isolated, int isolatedUid) {
        String proc = customProcess != null ? customProcess : info.processName;
        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
        final int userId = UserHandle.getUserId(info.uid);
        int uid = info.uid;
        if (isolated) {
            ……
        }
        //创建一个ProcessRecord对象,代表对应的进程。
        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
        if (!mBooted && !mBooting
                && userId == UserHandle.USER_SYSTEM
                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
            r.persistent = true;
            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
        }
        addProcessNameLocked(r);
        return r;
    }

ProcessRecord的成员较多,先来看看在其构造函数中都初始化了哪些成员变量。

【ProcessRecord.java::ProcessRecord】

ProcessRecord(BatteryStatsImpl _batteryStats, ApplicationInfo _info,
            String _processName, int _uid) {
        mBatteryStats = _batteryStats; //用于电量统计
        info = _info;  //保存ApplicationInfo
        isolated = _info.uid != _uid;
        uid = _uid;
        userId = UserHandle.getUserId(_uid);
        processName = _processName; //保存进程名
        //一个进程能运行多个 Package,pkgList用于保存package
        pkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.versionCode));
        //下面这些xxxAdj成员变量和进程高度优先级、OOM_adj有关。
        maxAdj = ProcessList.UNKNOWN_ADJ;
        curRawAdj = setRawAdj = ProcessList.INVALID_ADJ;
        curAdj = setAdj = verifiedAdj = ProcessList.INVALID_ADJ;
        //用于控制该进程是否常驻内存(即使被杀掉,系统也会重启它),只有重要的进程才会有此待遇
        persistent = false;
        removed = false;
        lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis();
    }

    ProcessRecord保存了进程名、不同状态对应的Oom_adj值及一个ApplicationInfo。一个进程虽然可运行多个Application,但是ProcessRecord一般保存该进程中先运行的那个Application的ApplicationInfo。

    至此,已经创建了一个ProcessRecord对象,和其他应用进程不同的是,该对象对应的进程为system_server。为了彰显其特殊性,AMS为其中的一些成员变量设置了特定的值:

【ActivityManagerService.java::setSystemProcess】

app.persistent = true;
app.pid = MY_PID;
app.maxAdj = ProcessList.SYSTEM_ADJ;
//另外,app的processName被设置成"system"

1.3 startBootstrapServices()分析

先回顾一下最开始的入口函数

【SystemServer.java::run()】

private void run() {
        try {
            //省略部分代码
            //HHHA:1====>Initialize the system context.
            createSystemContext();
            //省略部分代码
        } finally {
            traceEnd();  // InitBeforeStartServices
        }
 
        // Start services.
        try {
            traceBeginAndSlog("StartServices");
            //HHHA:2====>启动boot阶段服务
            startBootstrapServices();
            //HHHA:3====>启动核心服务
            startCoreServices();
            //HHHA:4====>启动其它服务
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            
        //省略部分代码
    }

现在是把HHHA:3====>展开,并省略与AMS无关的部分:

【SystemServer.java::startCoreServices】

private void startCoreServices() {
        // Records errors and logs, for example wtf()
        traceBeginAndSlog("StartDropBoxManager");
        mSystemServiceManager.startService(DropBoxManagerService.class);
        traceEnd();

        traceBeginAndSlog("StartBatteryService");
        // Tracks the battery level.  Requires LightService.
        mSystemServiceManager.startService(BatteryService.class);
        traceEnd();

        // Tracks application usage stats.
        traceBeginAndSlog("StartUsageService");
        mSystemServiceManager.startService(UsageStatsService.class);
        //HHHF:1====>应用使用情况
        mActivityManagerService.setUsageStatsManager(
                LocalServices.getService(UsageStatsManagerInternal.class));
        traceEnd();

        // Tracks whether the updatable WebView is in a ready state and watches for update installs.
        traceBeginAndSlog("StartWebViewUpdateService");
        mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
        traceEnd();
    }

似乎没什么好分析的

1.4 startOtherServices分析

【SystemServer.java::startOtherServices】

private void startOtherServices() {
    ……
    try {
            ……
            traceBeginAndSlog("InstallSystemProviders");
            //HHHG:1====>
            mActivityManagerService.installSystemProviders();
            traceEnd();
            ……
            traceBeginAndSlog("InitWatchdog");
            final Watchdog watchdog = Watchdog.getInstance();
            //HHHG:2====>
            watchdog.init(context, mActivityManagerService);
            traceEnd();
            ……
            traceBeginAndSlog("SetWindowManagerService");
            //HHHG:3====>
            mActivityManagerService.setWindowManager(wm);
            traceEnd();
        } catch (RuntimeException e) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting core service", e);
        }
        ……
        if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
            ……
            if (!disableNetwork) {
                traceBeginAndSlog("StartNetworkScoreService");
                ……
                traceBeginAndSlog("StartNetworkPolicyManagerService");
                try {
                    //HHHG:4====>
                    networkPolicy = new NetworkPolicyManagerService(context,
                            mActivityManagerService, networkStats, networkManagement);
                    ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
                } catch (Throwable e) {
                    reportWtf("starting NetworkPolicy Service", e);
                }
                traceEnd();
        ……
        }
        ……
        // Before things start rolling, be sure we have decided whether
        // we are in safe mode.
        final boolean safeMode = wm.detectSafeMode();
        if (safeMode) {
            traceBeginAndSlog("EnterSafeModeAndDisableJitCompilation");
            //HHHG:5====>开启安全模式
            mActivityManagerService.enterSafeMode();
            // Disable the JIT for the system_server process
            VMRuntime.getRuntime().disableJitCompilation();
            traceEnd();
        } else {
            // Enable the JIT for the system_server process
            traceBeginAndSlog("StartJitCompilation");
            VMRuntime.getRuntime().startJitCompilation();
            traceEnd();
        }
        ……
        if (safeMode) {
            //HHHG:6====>
            mActivityManagerService.showSafeModeOverlay();
        }
        ……
        traceBeginAndSlog("MakePowerManagerServiceReady");
        try {
            // TODO: use boot phase
            //HHHG:7====>
            mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService());
        } catch (Throwable e) {
            reportWtf("making Power Manager Service ready", e);
        }
        traceEnd();
        ……
        // We now tell the activity manager it is okay to run third party
        // code.  It will call back into us once it has gotten to the state
        // where third party code can really run (but before it has actually
        // started launching the initial applications), for us to complete our
        // initialization.
        //HHHG:8====>
        mActivityManagerService.systemReady(() -> {
            Slog.i(TAG, "Making services ready");
            traceBeginAndSlog("StartActivityManagerReadyPhase");
            mSystemServiceManager.startBootPhase(
                    SystemService.PHASE_ACTIVITY_MANAGER_READY);
            traceEnd();
            traceBeginAndSlog("StartObservingNativeCrashes");
            try {
                mActivityManagerService.startObservingNativeCrashes();
            } catch (Throwable e) {
                reportWtf("observing native crashes", e);
            }
            traceEnd();
         ……
}

1.4.1 AMS的installSystemProviders

  ContentProvider是用于在多个应用间共享数据而存在的机制,如果你的应用没有向外提供共享数据,则直接使用数据库就行了。而此处的应用是system_server它需要向几乎所有的其它共享数据,如语言设置等。该Provider在SettingsProvider.apk中,installSystemProviders就会加载该APK并把SettinsProvider放到system_server进程中来运行。

【ActivityManagerService.java::installSystemProviders】

public final void installSystemProviders() {
        List<ProviderInfo> providers;
        synchronized (this) {
            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
            //HHHH:1====>关键调用,见正文分析
            providers = generateApplicationProvidersLocked(app);
            if (providers != null) {
                for (int i=providers.size()-1; i>=0; i--) {
                    ProviderInfo pi = (ProviderInfo)providers.get(i);
                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
                        Slog.w(TAG, "Not installing system proc provider " + pi.name
                                + ": not system .apk");
                        providers.remove(i);
                    }
                }
            }
        }
        if (providers != null) {
            //HHHH:2====>:为SystemServer进程安装Provider
            mSystemThread.installSystemProviders(providers);
        }

        mConstants.start(mContext.getContentResolver());
        //监视Settings数据库中Secure表的变化,目前只关注long_press_timeout配置的变化
        mCoreSettingsObserver = new CoreSettingsObserver(this);
        mFontScaleSettingObserver = new FontScaleSettingObserver();

        // Now that the settings provider is published we can consider sending
        // in a rescue party.
        RescueParty.onSettingsProviderPublished(mContext);
        //《深入理解Android卷2》的分析中,这行是有效的,新版本不知为何注掉了
        //mUsageStatsService.monitorPackages();
    }

要点:

  • 调用generateApplicationProvidersLocked函数,该函数返回一个ProviderInfo List。
  • 调用ActivityThread的installSystemProviders函数。ActivityThread可以看做是进程的Android运行环境,那么installSystemProviders表示为该进程安装ContentProvider。

HHHH:1====>展开看看:

【ActivityManagerService.java::generateApplicationProvidersLocked】

private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
        List<ProviderInfo> providers = null;
        try {
            //向PKMS查询满足要求的ProviderInfo,最重要的查询条件包括:进程和进程uid
            providers = AppGlobals.getPackageManager()
                    .queryContentProviders(app.processName, app.uid,
                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
        ……
        if (providers != null) {
            int N = providers.size();
            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
            for (int i=0; i<N; i++) {
                //AMS对ContentProvider的管理,见正文主解释
                ProviderInfo cpi =
                    (ProviderInfo)providers.get(i);
                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
                        cpi.name, cpi.flags);
                ……

                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
                ……
                //将信息保存到ProcessRecord中
                app.pubProviders.put(cpi.name, cpr);
                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
                    // 保存PackageName到ProcessRecord中
                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
                            mProcessStats);
                }
                notifyPackageUse(cpi.applicationInfo.packageName,
                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
            }
        }
        return providers;
    }

generateApplicationProvidersLocked先从PKMS那里查询满足条件的ProviderInfo信息,而后将它们分别保存到AMS和ProcessRecord中对应的数据结构中。

HHHH:2====>展开:

【ActivityThreadjava::installSystemProviders】

    public final void installSystemProviders(List<ProviderInfo> providers) {
        if (providers != null) {
            installContentProviders(mInitialApplication, providers);
        }
    }

    private void installContentProviders(
            Context context, List<ProviderInfo> providers) {
        final ArrayList<ContentProviderHolder> results = new ArrayList<>();

        for (ProviderInfo cpi : providers) {
            if (DEBUG_PROVIDER) {
                StringBuilder buf = new StringBuilder(128);
                buf.append("Pub ");
                buf.append(cpi.authority);
                buf.append(": ");
                buf.append(cpi.name);
                Log.i(TAG, buf.toString());
            }
            //HHHI:1====>调用installProvider函数,得到一个IContentProvoder对象
            ContentProviderHolder cph = installProvider(context, null, cpi,
                    false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
            if (cph != null) {
                cph.noReleaseNeeded = true;
                results.add(cph);
            }
        }

        try {
            //HHHI:2====>调用AMS的publisthContentProviders注册这些ContentProvider
            //第一个参数为ApplicationThread
            ActivityManager.getService().publishContentProviders(
                getApplicationThread(), results);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }

  installContentProviders实际上是标准的ContentProvider安装时调用的程序。安装ContentProvider包括两方面的工作:

  • 先在ActivityThread中通过installProvider得到一个ContentProvider实例
  • 向AMS发布这个ContentProvider实例。如此这般,一个APK中声明的ContentProvider才能发挥其刻有的作用。
发布了90 篇原创文章 · 获赞 24 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/menghaocheng/article/details/103988993