美文网首页
ActivityManager

ActivityManager

作者: AI科技智库 | 来源:发表于2019-08-16 10:46 被阅读0次

    1.1 ActivityManger的组成

    ActivityManger的功能:

    • 启动管理应用进程
    • 启动调度Activity、Service的生命周期
    • 注册BroadcastReceiver、接收和分发广播
    • 启动发布ContentProvider
    • 调整进程调度优先级

    ActivityManger的组成:
    Android8.0之后,ActivityManagerNative已经被delete,ActivityManger使用IActivityManger.aidl文件,生成Binder通信的代理端和服务端。

    • Client端,由ActivityManger封装接口供client调用,通过 IActivityManagerSingleton.get()获取服务的代理对象。
    • Service端,由ActivityMangerService实现,继承了IActivityManager.Stub 接口,提供Server端的系统服务
    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;
                    }
             };
    

    1.2 系统如何启动ActivityMangerService

    AMS的启动是在SystemServer(系统进程)中进行启动的,android所有的进程都是由zygote fork出来的,SystemServer也不例外。

    private void run() {
            try {
                (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.setStartInfo(mRuntimeRestart,
                        mRuntimeStartElapsedTime, mRuntimeStartUptime);
                LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
                // Prepare the thread pool for init tasks that can be parallelized
                SystemServerInitThreadPool.get();
            } finally {
                traceEnd();  // InitBeforeStartServices
            }
            (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();
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
    
    
    • (1) Looper.prepareMainLooper()
      初始化MainLooper,ThreadLocal 线程本地存储区,每个线程都有自己私有的本地存储区,不同线程彼此不能访问对方的ThreadLocal。Looper.prepare() 新建一个Looper存入static的sThreadLocal,Looper内部维护一个MessageQueue。
    public static void prepareMainLooper() {
          prepare(false);
          synchronized (Looper.class) {
              if (sMainLooper != null) {
                  throw new IllegalStateException("The main Looper has already been prepared.");
              }
              sMainLooper = myLooper();
          }
    }
    
    
    • (2)createSystemContext方法
      创建一个ActivityThread对象,代表当前进程 (系统进程) 的主线程,创建一个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);
    }
    
    • (3)创建SystemServiceManager
      它会对系统的服务进行创建、启动和生命周期管理。

    • (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);
            ....
           //注册一些系统服务
           //将framework-res.apk的信息加入到SystemServer对应的LoadedApk中,
           //同时构建SystemServer进程对应的ProcessRecord, 以将SystemServer进程纳入到AMS的管理中。
            mActivityManagerService.setSystemProcess();
            mActivityManagerService.systemReady();
    ....
        }
    

    ActivityManagerService是使用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);
            }
            public ActivityManagerService getService() {
                return mService;
            }
     }
    

    1.3 ActivityManagerService启动细节

    1.3.1 第一阶段:创建ActivityThread

    ActivityThread负责管理应用程序所在进程的主线程(UI线程)的执行、调度和运行activity、broadcasts等操作。

    systemMain首先创建一个ActivityThread类型的thread对象,该对象返回后保存到AMS的mSystemThread对象中,传入true继续调用attach方法。

    public static ActivityThread systemMain() {
            if (!ActivityManager.isHighEndGfx()) {
                ThreadedRenderer.disable(true);
            } else {
                ThreadedRenderer.enableForegroundTrimming();
            }
            ActivityThread thread = new ActivityThread();
            thread.attach(true);
            return thread;
        }
    

    attach方法会区分系统进程和应用进程,传入参数true代表了系统进程,包括system_server以及AndroidManifest.xml中声明了android:shareUserId="android.uid.system"的apk(frameworks_res.apk、SettingsProvider.apk)

    private void attach(boolean system, long startSeq) {
            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 {
                    mInstrumentation = new Instrumentation();
                    mInstrumentation.basicInit(this);
                    ContextImpl context = ContextImpl.createAppContext(
                            this, getSystemContext().mPackageInfo);
                    mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                    mInitialApplication.onCreate();
                } catch (Exception e) {
                    throw new RuntimeException(
                            "Unable to instantiate Application():" + e.toString(), e);
                }
            }
             ...    
        }
    
    

    (1)系统Context的创建和初始化

    getSystemContext的作用是创建一个系统Context的单例,并初始化。

     public ContextImpl getSystemContext() {
            synchronized (this) {
                if (mSystemContext == null) {
                    //创建系统Context
                    mSystemContext = ContextImpl.createSystemContext(this);
                }
                return mSystemContext;
            }
    }
    
    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;
    }
    

    LoadApk的构造方法,通过mActivityThread成员变量关联当前ActivityThread,setResources将一个可以访问framework中定义的系统资源的Resources对象,设置到context。这样才能通过ContextImpl访问系统Resources。
    ContextImpl的构造函数主要是完成一些变量的初始化,建立起ContextImpl与ActivityThread、LoadedApk、ContentResolver之间的关系。ApplicationContentResolver是ContetResover的子类,用于访问ContentProvider。

    (2)创建Application对象

    public Application makeApplication(boolean forceDefaultAppClass,
                Instrumentation instrumentation) {
            ...
            Application app = null;
            try {
                java.lang.ClassLoader cl = getClassLoader();
                ...
                ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
                app = mActivityThread.mInstrumentation.newApplication(
                        cl, appClass, appContext);
                appContext.setOuterContext(app);
            } catch (Exception e) {
                ...
            }
            mActivityThread.mAllApplications.add(app);
            mApplication = app;
    
            if (instrumentation != null) {
                try {
                    instrumentation.callApplicationOnCreate(app);
                } catch (Exception e) {
                    if (!instrumentation.onException(app, e)) {
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                        throw new RuntimeException(
                            "Unable to create application " + app.getClass().getName()
                            + ": " + e.toString(), e);
                    }
                }
            }
            ...
            return app;
    }
    
    

    newApplication通过反射机制创建Application对象,将其与系统Context关联在一起。

    static public Application newApplication(Class<?> clazz, Context context)
                throws InstantiationException, IllegalAccessException,
                ClassNotFoundException {
            Application app = (Application)clazz.newInstance();
            app.attach(context);
            return app;
    }
    
    

    Application继承自ContextWrapper,attach调用attachBaseContext将系统context保存到ContextWrapper.mBase成员变量中,然后读取Context保存的LoadedApk,并将其存入mLoadedApk中。

        final void attach(Context context) {
            attachBaseContext(context);
            mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
        }
    
    

    1.3.2 第二阶段:AMS.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、注册了一些其他服务,meminfo,gfxinfo用于调试,permission用于检查进程权限,
    2、通过PM获取package名为“android”的应用的ApplicationInfo;
    3、调用ActivityThread的installSystemApplicationInfo;
    4、创建并处理ProcessRecord。

    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集合中。

    1.3.3 第三阶段:AMS.systemReady()

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

    相关文章

      网友评论

          本文标题:ActivityManager

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