(转)ActivityManagerService启动过程(基于android 8.0)

https://www.jianshu.com/p/8d4e17836322

下边这个图是7.0 的

 

AMS类的结构,copy自网络

 

1.看得出AMS 实现了看门狗(Watchdog.Monitor)以及电量监控(BatteryStatsImpl.BatteryCallback) 接口,并且继承了ActivityManagerNative
2.ActivityManagerNative实现了IActivityManager,使用Binder来跟应用程序进行通信,只不过这里AMN内部增加了一个代理类解藕,最终其他进程要跟AMS交互还是使用Binder机制。
这里很好玩的是8.0系统上ActivityManagerNative上已经被delete

/**
 * {@hide}
 * @deprecated will be removed soon. See individual methods for alternatives.
 */
@Deprecated
public abstract class ActivityManagerNative

而且本身的AMS的继承类也相应的变化了:

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

这里的它的区别是继承了IActivityManager.Stub 接口类,了解Bindler机制的人应该知道此处应该是一个IActivityManager.aidl生成的java类。只不过这里android可能删除了ActivityManagerNative这个类,并把一些Binder代码转化为了AIDL模版方式。
可以看下下边两个sdk中的代码:
8.0上:
ActivityManagerNative.class中的代码:

 /**
     * Retrieve the system's default/global activity manager.
     *
     * @deprecated use ActivityManager.getService instead.
     */
    static public IActivityManager getDefault() {
        return ActivityManager.getService();
    }

ActivityManager.class 中的代码:

    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

7.0上:
ActivityManagerNative.class中的代码:

/**
*获得IActivityManager类
*/
static public IActivityManager getDefault() {
        return gDefault.get();
    }

static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
 
        return new ActivityManagerProxy(obj);

ActivityManager.class 中的代码:

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);//注意这一行
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

可以看得出来,两个的写法不一样,本质上都是一样的,只不过这里android可能使用了统一的AIDL方式进行ipc,减少了代码的维护。所以我们在写ipc的时候还是使用aidl模版比较好,利于维护。

好了有点扯远了,回到正题上AMS的启动过程:

AMS的启动是在SystemServer(系统进程)中进行启动的,我们知道android所有的进程都是由zygote fork出来的,SystemServer也不例外。下边捋一下SystemServer的代码:

SystemServer

/**
     * The main entry point from zygote.
     */
//很清楚看到是由zygote进程fork来的
    public static void main(String[] args) {
        new SystemServer().run();
    }

run方法:

private void run() {
           ....
             (1)
            Looper.prepareMainLooper();

            // Initialize native services.
            System.loadLibrary("android_servers");
          ....
             (2)
            // Initialize the system context.
            createSystemContext();  
             (3)
            // Create the system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext); 
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
           ....
          (4) 
        // Start services.
        try {
            traceBeginAndSlog("StartServices");
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }
        ....
        // Loop forever.
        Looper.loop();
         (5)
        throw new RuntimeException("Main thread loop unexpectedly exited");
}
  • (1).Looper.prepareMainLooper();方法:

初始化MainLooper,这里可以看得出我们这个SystemServer本身可能就是一个应用进程。
这里稍微扩展一下Looper.prepareMainLooper()函数是创建了一个全局静态的sMainLooper,创建函数是:

private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }

1.这里我当时没想明白是怎么把ActivityThread跟Looper进行绑定的,毕竟ActivityThread是在Looper初始化之后new的,而Looper的new过程是伴随着绑定当前线程的。这里我们一定要注意:
ActivityThread不是一个线程,尽管以此命名,我们new的ActivityThread只不过是一个普通类。同时行使主线程的能力罢了。
2.这里的Looper是使用sThreadLocal保证全局唯一的,ThreadLocal也是一个很有意思的类,它可以看作是一个Map的工具类,使用统一的工具类管理各个分散在不同Thread中的ThreadLocalMap,以ThreadLocal为key,管理各个thread中map值,当然这里必须使用弱引用防止内存问题。这种统一管理方式很值得学习。

  • (2)createSystemContext方法:

1.得到了一个ActivityThread对象,它代表当前进程 (此时为系统进程) 的主线程;
2.得到了一个Context对象,对于SystemServer而言,它包含的Application运行环境与framework-res.apk有关。

private void createSystemContext() {
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

        final Context systemUiContext = activityThread.getSystemUiContext();
        systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
    }
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();
        thread.attach(true);
        return thread;
    }
  • (3)创建SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理。
  • (5)throw new RuntimeException("Main thread loop unexpectedly exited");

这里一种防止Looper quit的一种方式

  • (4) 启动各种service,这里startBootstrapServices ()方法是初始化AMS的,只需要看此方法即可
      private void startBootstrapServices() {
....
        Installer installer = mSystemServiceManager.startService(Installer.class);
....
        // Activity manager runs the show.
        //真正启动AMS的地方
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
....
// Set up the Application instance for the system process and get started. 
    //注册一些系统服务
//将framework-res.apk的信息加入到SystemServer对应的LoadedApk中,
//同时构建SystemServer进程对应的ProcessRecord, 以将SystemServer进程纳入到AMS的管理中。
        mActivityManagerService.setSystemProcess();
....
    }

可以看出AMS是使用SystemServiceManager(SSM)启动的,SSM启动的service必须继承自final Class<SystemService> serviceClass;,但是这里因为AMS并不是,所以使用了ActivityManagerService.Lifecycle.class类。

    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();
        }

        public ActivityManagerService getService() {
            return mService;
        }
    }

很简单这只不过是AMS 的代理类,也是为了解藕,这种启动Service的处理方式蛮特别的。可以学习下SystemServiceManager的源码,这里不做深入。

这里Lifecycle.class中有两步操作 ,

  1. mService = new ActivityManagerService(context);
// Note: This method is invoked on the main thread but may need to attach various
    // handlers to other threads.  So take care to be explicit about the looper.
    public ActivityManagerService(Context systemContext) {
        ...
        mServices = new ActiveServices(this);
        mProviderMap = new ProviderMap(this);
        mAppErrors = new AppErrors(mUiContext, this);
        ...
        Watchdog.getInstance().addMonitor(this);
        Watchdog.getInstance().addThread(mHandler);
    }

可以看得出来AMS的构造方法中都是一些初始化操作,以及增加了看门狗

  1. mService.start();
private void start() {
        //完成统计前的复位工作
        removeAllProcessGroups();
        //开始监控进程的CPU使用情况
        mProcessCpuThread.start();
        //注册服务
        mBatteryStatsService.publish(mContext);
        mAppOpsService.publish(mContext);
        Slog.d("AppOps", "AppOpsService published");
        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
        // Wait for the synchronized block started in mProcessCpuThread,
        // so that any other acccess to mProcessCpuTracker from main thread
        // will be blocked during mProcessCpuTracker initialization.
        try {
            mProcessCpuInitLatch.await();
        } catch (InterruptedException e) {
            Slog.wtf(TAG, "Interrupted wait during start", e);
            Thread.currentThread().interrupt();
            throw new IllegalStateException("Interrupted wait during start");
        }
    }

主要处理了:
1、启动CPU监控线程。该线程将会开始统计不同进程使用CPU的情况。
2、发布一些服务,如BatteryStatsService、AppOpsService(权限管理相关)和本地实现的继承ActivityManagerInternal的服务。

看上边的startBootstrapServices方法中mActivityManagerService.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) {
                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);
            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());

            synchronized (this) {
                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
                app.persistent = true;
                app.pid = MY_PID;
                app.maxAdj = ProcessList.SYSTEM_ADJ;
                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
                synchronized (mPidsSelfLocked) {
                    mPidsSelfLocked.put(app.pid, app);
                }
                updateLruProcessLocked(app, false, null);
                updateOomAdjLocked();
            }
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(
                    "Unable to find android system package", e);
        }
    }

此方法中主要处理了
1、注册一些服务;
2、获取package名为“android”的应用的ApplicationInfo;
3、调用ActivityThread的installSystemApplicationInfo;
4、AMS进程管理相关的操作。

这里注意installSystemApplicationInfo ()方法:它主要处理了将package名为“android”的应用的ApplicationInfo;(即framework-res.apk,资源apk)赋值给LoadedApk,这里不详细拆分
SystemServer.run()startOtherServices();方法中有一类似的代码mActivityManagerService.installSystemProviders();此方法是加载运行在SystemServer进程中的ContentProvider,即SettingsProvider.apk (定义于frameworks/base/packages/SettingsProvider)。最终ContentProvider信息都将注册到AMS中的mProviderMap集合中。

最后一步SystemSever#startOtherServices中调用ActivityManagerService#systemReady方法

public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
...
//通知一些服务可以进行systemReady相关的工作,并进行启动服务或应用进程的工作
...
//开启HomeActivity
startHomeActivityLocked(currentUserId, "systemReady");
...
}

到此我们的AMS已经启动完全,后续是Activity的启动流程,这里不做讲解。

鉴于时间限制,我就盗用下边的流程图作为总结吧。。。。

 

AMS的启动流程图

其他:

  • AMS的通信机制:(使用AIDL)

APP向AMS发起进程间通信:(IActivityManager.aidl)
ActivityManger.getService() 获得AMS的Binder接口,在通过Stub.asInterface的方式,转成IActivityManager的接口。然后就可以通过IActivityManager向AMS发起进程间通信。

// android/app/Instrumentation.java
int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target, requestCode, 0, null, options);

// android/app/ActivityManager.java
public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }
 
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

AMS向APP发起进程间通信:(IApplication.aidl)
在AMS内部持有每个ActivityThread的IApplication接口实例,用时可以直接调用。当然这里也是Binder通信。
其实在ActivityThread.main()时会调用attach(bool)方法

private void attach(boolean system) {
      ...
        if (!system) {
           ...
            final IActivityManager mgr = ActivityManager.getService();
            try {
                //将IApplication注册给AMS
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
           ...
    }
 @Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
           ...
            attachApplicationLocked(thread, callingPid);
          ...  
        }
    }
private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
...
        updateLruProcessLocked(app, false, null);
...
 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
            ProcessRecord client) {
...
        //AMS中 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
         mLruProcesses.add(app);
...

反正一系列的方法最后将IApplication传递到了AMS中,等到AMS调用APP时使用。看下图:

 

AMS跟应用进程通信

  • AMS本身运行在SystemServer 中,但同时也管理SystemServer(可以看作一个特殊APP)

  • SettingProvider.apk

SettingProvider.apk 给Settings应用提供设置默认值、设置存储和设置修改服务。其源码在frameworks/base/packages目录下。其apk在设备上的位置:/system/priv-app/SettingsProvider。本次对SettingProvider的修改主要针对一些设置默认值

Framework-res.apk

系统默认的一些资源信息

  • tag:AMS启动流程,通信机制

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值