Android核心分析之AMS

ActivityManagerService 简称AMS,是Android内核的核心功能之一,在系统启动SystemServer时启动此服务。

android 框架:

《Android核心分析之AMS》

Activity Manager的组成主要分为以下几个部分:

   1.服务代理:由ActivityManagerProxy实现,用于与Server端提供的系统服务进行进程间通信

  2.服务中枢:ActivityManagerNative继承自Binder并实现IActivityManager,它提供了服务接口和Binder接口的相互转化功能,并在内部存储服务代理对像,并提供了getDefault方法返回服务代理

  3.Client:由ActivityManager封装一部分服务接口供Client调用。ActivityManager内部通过调用ActivityManagerNative的getDefault方法,可以得到一个ActivityManagerProxy对像的引用,进而通过该代理对像调用远程服务的方法

   4.Server:由ActivityManagerService实现,提供Server端的系统服务

框架图:

《Android核心分析之AMS》

AMS提供的功能主要包括以下几个方面:

   1。对于Android四大组件(activity service broadcast content provider)的管理,包括启动,生命周期管理等

    2.进程OOM adj以级LRU weight管理

AMS主要代码位于:

frameworks\base\core\java\android\app

frameworks\base\services\java\com\android\server\am

主要目录结构如下:

《Android核心分析之AMS》

《Android核心分析之AMS》

《Android核心分析之AMS》

AMS服务启动是系统启动的init2阶段,由SystemServer启动的Java系统服务之一,启动代码位于\frameworks\base\services\java\com\android\server\SystemServer.java中

AMS服务在系统启动阶段的主要工作:

1.调用main方法启动AMS服务  context = ActivityManagerService.main(factoryTest);
2.调用SetSystemProcess方法ActivityManagerService。setSystemProcess();

3.调用installSystemProviders方法ActivityManagerService.installSystemProviders();

4.调用SystemReady方法 ActivityManagerService.self().systemReady

main方法介绍:

启动AThread线程,创建ActivityManagerService

创建完毕后,调用ActivityThread的systemMain方法创建ActivityThread对像

调用ActivityThread对像的getSystemContext方法创建Context对像,初始化ActivityStack

调用AMS的startRunning方法

public static final Context main(int factoryTest) {
        AThread thr = new AThread();
        thr.start();

        synchronized (thr) {
            while (thr.mService == null) {
                try {
                    thr.wait();
                } catch (InterruptedException e) {
                }
            }
        }

        ActivityManagerService m = thr.mService;
        mSelf = m;
        ActivityThread at = ActivityThread.systemMain();
        mSystemThread = at;
        Context context = at.getSystemContext();
        context.setTheme(android.R.style.Theme_Holo);
        m.mContext = context;
        m.mFactoryTest = factoryTest;
        m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());

        // CHANGED BY MARS BEGIN
        m.mStackSupervisor = new com.marvell.security.MrvlActivityStackSupervisor(m, context, thr.mLooper);
        // CHANGEd BY MARS END

        m.mBatteryStatsService.publish(context);
        m.mUsageStatsService.publish(context);
        m.mAppOpsService.publish(context);

        synchronized (thr) {
            thr.mReady = true;
            thr.notifyAll();
        }

        m.startRunning(null, null, null, null);

        return context;
    }

setSystemProcess介绍

•注册服务。首先将ActivityManagerService注册到ServiceManager中,其次将几个与系统性能调试相关的服务注册到ServiceManager。 •查询并处理ApplicationInfo。首先调用PackageManagerService的接口,查询包名为android的应用程序的ApplicationInfo信息,对应于framework-res.apk。然后以该信息为参数调用ActivityThread上的installSystemApplicationInfo方法。 •创建并处理ProcessRecord。调用ActivityManagerService上的newProcessRecordLocked,创建一个ProcessRecord类型的对象,并保存该对象的信息。

 public static void setSystemProcess() {
        try {
            ActivityManagerService m = mSelf;

            ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);
            ServiceManager.addService(ProcessStats.SERVICE_NAME, m.mProcessStats);
            ServiceManager.addService("meminfo", new MemBinder(m));
            ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
            ServiceManager.addService("dbinfo", new DbBinder(m));
            if (MONITOR_CPU_USAGE) {
                ServiceManager.addService("cpuinfo", new CpuBinder(m));
            }
            ServiceManager.addService("permission", new PermissionController(m));

            ApplicationInfo info =
                mSelf.mContext.getPackageManager().getApplicationInfo(
                            "android", STOCK_PM_FLAGS);
            mSystemThread.installSystemApplicationInfo(info);

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

installSystemProviders
介绍 •调用generateApplicationProvidersLocked查询Content Provider •调用ActivityThread.installSystemProviders安装Content Provider

        generateApplicationProvidersLocked首先从PackageManagerService中查询运行在system进程中且UID为SYSTEM_UID的Content Provider的信息,只有SettingsProvider满足此种条件,第二步installSystemProviders就是安装上述查询出来的SettingsProvider

 public static final void installSystemProviders() {
        List<ProviderInfo> providers;
        synchronized (mSelf) {
            ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
            providers = mSelf.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) {
            mSystemThread.installSystemProviders(providers);
        }

        mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);

        mSelf.mUsageStatsService.monitorPackages();
    }

SystemReady
介绍 •发送处理ACTION_PRE_BOOT_COMPLETED广播 •清理提前启动的非persistent进程 •读取Settings配置 •调用goingCallback的run函数启动SystemUI,执行其他系统服务的systemReady方法,启动软件Watchdog。 •启动persistent应用和Home应用,发送ACTION_BOOT_COMPLETED广播。

启动
Activity
的方法主要有以下的


:

 1.startActvity

 2. startActivityForResult

这些方法都是通过Binder机制的Client端,调用Server端的ActivityManagerService的startActivity系列方法,最终启动指定的activity

Activity
启动流程图:

《Android核心分析之AMS》

Activity
启动模式有四种: •standard •singleTop •singleTask •singleInstance

为什么需要广播

  广播是操作系统framework层对观察者模式(observer)最常用的实现方式

  一个软件系统常常要求在某一个对象的状态发生变化的时候,某些其它的对象做出相应的改变。做到这一点的设计方案有很多,但是为了使系统能够易于复用,应该选择低耦合度的设计方案。减少对象之间的耦合有利于系统的复用,但是同时设计师需要使这些低耦合度的对象之间能够维持行动的协调一致,保证高度的协作。观察者模式是满足这一要求的各种设计方案中最重要的一种。

广播发送的
api
有:
•sendBroadcast
•sendOrderBroadcast
•sendStickyBroadcast

监听广播的方式有:
•动态注册使用registerReceiver方式
•静态注册在AndroidManifest.xml中定义BroadcastReceiver类并实现


广播有哪几种

     广播有无序广播、有序广播和粘性广播,其中粘性广播需要有BROADCAST_STICKY权限

《Android核心分析之AMS》

Service
是什么

    Service是Android系统的组件之一,和Activity,Broadcast,Conent Provider并称Android四大组件,Service是不可见的,是没有界面的,是在后台运行的,Service一般处理比较耗时以及长时间运行的操作

Service
的启动有两种方式:

 1. startService主要用于启动一个服务执行后台任务,不进行通信,停止服务使用stopService

《Android核心分析之AMS》

 2. bindService该方法启动的服务可以获得该service的状态,停止服务使用unbindService

《Android核心分析之AMS》

Service
的重启机制:

onStartCommand(Intent,int,int)方法,这个方法return一个int值,return 的值有四种:

START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。

START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。

START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。

START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

Android
的四种数据存储方式 •SharedPreference

    一个xml文件,常用于存储较简单的参数设置

•SQLite

     SQLite是一个轻量级的数据库,支持基本SQL语法,是常被采用的一种数据存储方式

•File

     文件(I/O)存储方法,常用于存储大数量的数据

•Content Provider

    Android系统中能实现所有应用程序共享的一种数据存储方式

Content Provider
的设计思路 •安全性考虑 •独立性考虑 •封装性考虑 •跨进程考虑

Content Provider的发布是在应用进程启动时发布的,具体代码可见ActivityThread.java

AMS负责记录provider的调度端信息,并对其进行管理

Android为了提升当用户再次进入应用时的速度,采取了进程活动停止后不结束该进程的策略,将这些进程都保留在内存中,直到系统需要更多的内存为止。AMS为内存管理提供了OOM adj机制。

OOM adj(Out Of Memory adjustment)是内存不足状态的调整级别,系统根据进程运行时占有内存和CPU等情况为每个进程计算一个adj值,该值的取值范围为-17+15adj值越大的进程越容易被杀死,可以通过

           cat /proc/<pid>/oom_score_adj

     命令查看指定进程的OOM adj值,为方便管理,android在框架层定义了13个级别

后台隐藏的应用进程,运行于该进程的
Activity
是不可见的,杀死该进程不会对用户体验有较大的影响,其
adj
取值为
9

15

    static intHIDDEN_APP_MAX_ADJ = 15;

    static intHIDDEN_APP_MIN_ADJ = 9;

  

前一个应用程序所在进程
adj

    static intPREVIOUS_APP_ADJ = 7;

运行
Home
的应用程序进程

    static intHOME_APP_ADJ = 6;

不可见,但运行了用户可以感知的组件的应用程序进程,例如说在后台运行的音乐播放器

    static intPERCEPTIBLE_APP_ADJ = 2;

 

运行了可见
Activity
,但是并不在前台显示的应用程序进程

    static intVISIBLE_APP_ADJ = 1;

当前前台正在运行的应用程序所在的进程

    static intFOREGROUND_APP_ADJ = 0;

系统
persistent
进程,例如说
phone

incallui

    static final intPERSISTENT_PROC_ADJ = -12;

 

system
进程

   static final intSYSTEM_ADJ = -16;


Android借鉴了Linux进程管理机制,提供了自己的实现Low Memory KillerLMK其源码在kernel/drivers/staging/android/lowmemorykiller.c

     文件中,其中OOM adj等级由/sys/module/lowmemorykiller/parameters/adj指定,

    最小内存阈值由/sys/module/lowmemorykiller/parameters/minfree指定

    上述两个取值可以通过下列两个命令获取 

    cat /sys/module/lowmemorykiller/parameters/adj

    cat /sys/module/
lowmemorykiller
/parameters/
minfree

LMK
机制其选择进程杀死的原则是:

OOM
adj
越大的进程越容易被杀死

相同
adj
的进程,占用内存越大的越容易被杀死

未达到最小内存阈值的最大值时,不会选择进程杀死

LRU(Least Recently Used)是最近最少使用的意思,LRU weight用于衡量最近最少使用的权重,是Anroid进程管理的核心概念之一。

         Android应用进程启动后都会在AMS的成员变量中保存ProcessRecord信息,用于调度应用程序组件。此外,mLruProcessLRU顺序存储了当前运行的应用程序进程信息,其第一个元素便是最近最少使用的进程对应的ProcessRecord,用于管理应用程序进程。

以下三种情况发生时可以更新
mLruProcess


应用程序异常退出:调用
handleAppDiedLocked
更新
mLruProcesses

显式“杀死”指定进程:调用
ActivityManagerService
显式“杀死”进程时更新

启动和调度应用程序四大组件:调用
updateLruProcessLocked
更新

应用可以通过以下api获取进程信息:


getRunningTasks
获取系统正在运行的任务

getRunningAppProcesses
获取系统里正在运行的进程

killBackgroundProcesses
(String
packageName
)
立即杀
掉给定包名的进程,释放进程占用的资源
(
内存等
)

getMemoryInfo
(
MemoryInfo
outInfo
)
获取系统可用内存信息,数据封装在
outInfo
对象上

getProcessMemoryInfo
(
int
[]
pids
)
获取每个进程
ID(
集合
)
占用的内存大小
(
集合
),
pid

MemoryInfo
是一一对应的
getRunningServices
获取系统正在运行的服务的信息

    原文作者:护士leo
    原文地址: https://blog.csdn.net/tfslovexizi/article/details/43968173
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞