文章出处:http://blog.csdn.net/shift_wwx


前言:之前 android SystemServer详解分析了一下systemserver的启动过程,虽然分析下来很多繁琐,可是systemserver却是android启动的第一步,很多service都是在这个进程中启动,这些才是组成android的关键,AMS可以说是android应用的最关键的一个service,传说中的android四大组件就是用它来控制的。我根据源码做一些分析,不足应该很多,希望大神能多指点。


AMS最开始涉及到是在systemserver中:

context = ActivityManagerService.main(factoryTest);
    public static final Context main(int factoryTest) {        AThread thr = new AThread();//创建一个Looper,实例化AMS        thr.start();        synchronized (thr) {            while (thr.mService == null) {//等待AMS实例化完成                try {                    thr.wait();                } catch (InterruptedException e) {                }            }        }        ActivityManagerService m = thr.mService;//mSelf就是实例化的AMS        mSelf = m;        ActivityThread at = ActivityThread.systemMain();//实例化ActivityThread        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());        m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper);//activity堆栈管理类        m.mBatteryStatsService.publish(context);        m.mUsageStatsService.publish(context);        m.mAppOpsService.publish(context);        synchronized (thr) {//mSelf初始化成功后,就可以让AThread中Looper loop起来            thr.mReady = true;            thr.notifyAll();        }        m.startRunning(null, null, null, null);//调用startRuuning        return context;    }
注意code中的注释。

1)AThread

    static class AThread extends Thread {        ActivityManagerService mService;        Looper mLooper;        boolean mReady = false;        public AThread() {            super("ActivityManager");        }        @Override        public void run() {            Looper.prepare();            android.os.Process.setThreadPriority(                    android.os.Process.THREAD_PRIORITY_FOREGROUND);            android.os.Process.setCanSelfBackground(false);            ActivityManagerService m = new ActivityManagerService();            synchronized (this) {                mService = m;                mLooper = Looper.myLooper();                Watchdog.getInstance().addThread(new Handler(mLooper), getName());                notifyAll();            }            synchronized (this) {                while (!mReady) {                    try {                        wait();                    } catch (InterruptedException e) {                    }                }            }            // For debug builds, log event loop stalls to dropbox for analysis.            if (StrictMode.conditionallyEnableDebugLogging()) {                Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");            }            Looper.loop();        }    }

这个是AMS中的static class,为AMS创建了一个thread,区别去system_server进程的main thread,然后为AMS创建一个Looper,然后调用Looper.loop(); 另一个目的是实例化一个AMS。


private ActivityManagerService() {        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT, false);        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT, true);        mBroadcastQueues[0] = mFgBroadcastQueue;        mBroadcastQueues[1] = mBgBroadcastQueue;        mServices = new ActiveServices(this);        mProviderMap = new ProviderMap(this);        File dataDir = Environment.getDataDirectory();        File systemDir = new File(dataDir, "system");        systemDir.mkdirs();                ......}
构造函数就不详细的列出来,可以看一下AMS.java的source code。

一些变量需要注意,mBroadcastQueues(mFgBroadcastQueue、mBgBroadcastQueue)、mServices、mProviderMap四大组件三个在这里出现了,另外一个后期介绍。另外还有其他变量,mBatteryStatsService、mProcessStats、mUsageStatsService、mAppOpsService、mGrantFile、mStartedUsers、mCompatModePackages、mProcessCpuThread等等。

从code看,是在/data/system/下,创建了一些文件来管理android系统一些状态,例如batterystats.bin就是电池状态,接着procstats管理进程的,appops.xml就是app 权限相关的等等,后期会做详细的分析。


2)通过上面分析AThread后mSelf = m;

mSelf是static类型的,下面要讲到的mSystemThread也是static。


3)ActivityThread.systemMain()

    public static ActivityThread systemMain() {        HardwareRenderer.disable(true);//初始化hardwareRenderer        ActivityThread thread = new ActivityThread();//引入ResourceManager        thread.attach(true);        return thread;    }

主要是ActivityThread.attach():

    private void attach(boolean system) {        sCurrentActivityThread = this;        mSystemThread = system;        if (!system) {            ViewRootImpl.addFirstDrawHandler(new Runnable() {                @Override                public void run() {                    ensureJitEnabled();                }            });            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",                                                    UserHandle.myUserId());            RuntimeInit.setApplicationObject(mAppThread.asBinder());            IActivityManager mgr = ActivityManagerNative.getDefault();            try {                mgr.attachApplication(mAppThread);            } catch (RemoteException ex) {                // Ignore            }        } 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();                ContextImpl context = new ContextImpl();                context.init(getSystemContext().mPackageInfo, null, this);                Application app = Instrumentation.newApplication(Application.class, context);                mAllApplications.add(app);                mInitialApplication = app;                app.onCreate();            } catch (Exception e) {                throw new RuntimeException(                        "Unable to instantiate Application():" + e.toString(), e);            }        }        // add dropbox logging to libcore        DropBox.setReporter(new DropBoxReporter());        ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {            @Override            public void onConfigurationChanged(Configuration newConfig) {                synchronized (mResourcesManager) {                    // We need to apply this change to the resources                    // immediately, because upon returning the view                    // hierarchy will be informed about it.                    if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {                        // This actually changed the resources!  Tell                        // everyone about it.                        if (mPendingConfiguration == null ||                                mPendingConfiguration.isOtherSeqNewer(newConfig)) {                            mPendingConfiguration = newConfig;                                                        sendMessage(H.CONFIGURATION_CHANGED, newConfig);                        }                    }                }            }            @Override            public void onLowMemory() {            }            @Override            public void onTrimMemory(int level) {            }        });    }
(1)android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId());
ddm是Dalvik Debug Monitor缩写, 具体干嘛的不清楚,谁指点一下哦?

(2)Instrumentation类

(3)context

context第一次真正出现应该就是这里了:

ContextImpl context = new ContextImpl();context.init(getSystemContext().mPackageInfo, null, this);

虽然这里的context只是函数内局部变量,可是真正做的事情却很多。

先来看getSystemContext():

    public ContextImpl getSystemContext() {        synchronized (this) {            if (mSystemContext == null) {                ContextImpl context =                    ContextImpl.createSystemContext(this);                LoadedApk info = new LoadedApk(this, "android", context, null,                        CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);                context.init(info, null, this);                context.getResources().updateConfiguration(mResourcesManager.getConfiguration(),                        mResourcesManager.getDisplayMetricsLocked(Display.DEFAULT_DISPLAY));                mSystemContext = context;                //Slog.i(TAG, "Created system resources " + context.getResources()                //        + ": " + context.getResources().getConfiguration());            }        }        return mSystemContext;    }
这里主要的目的是创建mSystemContext:

static ContextImpl mSystemContext = null;
这可是系统一直用到的,所以上面提到的context虽然是临时的,但是目的却很关键。
继续看,context是通过ContextImpl.createSystemContext(this);来创建的:

    static ContextImpl createSystemContext(ActivityThread mainThread) {        final ContextImpl context = new ContextImpl();        context.init(Resources.getSystem(), mainThread, Process.myUserHandle());        return context;    }
需要说明一下Resources.getSytem():

    public static Resources getSystem() {        synchronized (sSync) {            Resources ret = mSystem;            if (ret == null) {                ret = new Resources();                mSystem = ret;            }            return ret;        }    }
还记得 android zygote之启动过程分析中提到的zygoteInit.main?其中有个preload();而随后 android 系统资源的加载和获取解析了过程,其中最关键的就是:

mResources = Resources.getSystem();
而这个mSystem是个static,所以这里ret在zygote的时候就注定了以后不会再为null了。包括Resources的构造函数中的mAssets也是static类型,这也是再zygote的时候定义好了的。
讲完了Resources.getSystem,再来看一下context.init函数:

    final void init(Resources resources, ActivityThread mainThread, UserHandle user) {        mPackageInfo = null;        mBasePackageName = null;        mOpPackageName = null;        mResources = resources;        mMainThread = mainThread;        mContentResolver = new ApplicationContentResolver(this, mainThread, user);        mUser = user;    }
作为systemcontext,这个时候mPackageInfo 等还是null,返回ActivityThread中继续看一下getSystemContext,讲完了createSystemContext,继续看一下一直会看到的packageInfo,这个对象的类型是LoadedApk:

LoadedApk info = new LoadedApk(this, "android", context, null,    CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
LoadedApk是加载apk的相关类,详细的code不贴了,可以看到LoadedApk有两个构造函数,一个是针对普通apk的, 另一个是针对systemcontext的。这里的构造函数目的是创建了ApplicationInfo,还有就是mClassLoader、mResources等,不过注意mApplicationInfo.packageName、mPackageName都是等于“android”。注意这个LoadedApk构造函数,包括这个“android”等会有介绍到。

LoadedApk创建玩之后会再一次调用context.init:

    final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread) {        init(packageInfo, activityToken, mainThread, null, null, Process.myUserHandle());    }    final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread,            Resources container, String basePackageName, UserHandle user) {        mPackageInfo = packageInfo;        if (basePackageName != null) {            mBasePackageName = mOpPackageName = basePackageName;        } else {            mBasePackageName = packageInfo.mPackageName;            ApplicationInfo ainfo = packageInfo.getApplicationInfo();            if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) {                // Special case: system components allow themselves to be loaded in to other                // processes.  For purposes of app ops, we must then consider the context as                // belonging to the package of this process, not the system itself, otherwise                // the package+uid verifications in app ops will fail.                mOpPackageName = ActivityThread.currentPackageName();            } else {                mOpPackageName = mBasePackageName;            }        }        mResources = mPackageInfo.getResources(mainThread);        mResourcesManager = ResourcesManager.getInstance();        CompatibilityInfo compatInfo =                container == null ? null : container.getCompatibilityInfo();        if (mResources != null &&                ((compatInfo != null && compatInfo.applicationScale !=                        mResources.getCompatibilityInfo().applicationScale)                || activityToken != null)) {            if (DEBUG) {                Log.d(TAG, "loaded context has different scaling. Using container's" +                        " compatiblity info:" + container.getDisplayMetrics());            }            if (compatInfo == null) {                compatInfo = packageInfo.getCompatibilityInfo();            }            mDisplayAdjustments.setCompatibilityInfo(compatInfo);            mDisplayAdjustments.setActivityToken(activityToken);            mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),                    Display.DEFAULT_DISPLAY, null, compatInfo, activityToken);        } else {            mDisplayAdjustments.setCompatibilityInfo(packageInfo.getCompatibilityInfo());            mDisplayAdjustments.setActivityToken(activityToken);        }        mMainThread = mainThread;        mActivityToken = activityToken;        mContentResolver = new ApplicationContentResolver(this, mainThread, user);        mUser = user;    }
这里应该是进一步的初始化mSystemContext了,之前的init说过,mPackageInfo等都是null,这里就详细的赋值了。mPackageInfo就是之前创建的LoadedApk,mBasePackageName、mOpPackageName都是之前创建LoadedApk传进来的“android”,mResources、mResourcesManager不用多说了,之前都介绍过了。

到这里这个ActivityThread 中这个static mSystemContext就完全创建ok了。

回到最开始,这里context是真正第一次出现,这里发现context.init跟getSystemContext中的context.init重复了,不知道google当初是怎么想的。

(4)创建application对象app

Application app = Instrumentation.newApplication(Application.class, context);mAllApplications.add(app);mInitialApplication = app;app.onCreate();

这里具体的没有明白?

刚开始我也不太清楚,整个过程到底是干什么?显示实例化一个局部的context变量,而不是全局的,利用这个context只是做一个init,在init的时候会传入LoadedApk,这个应该是apk的所有相关信息的集合,为什么会在这里体现出来,而且LoadedApk构造的时候传入了一个package name是android,直到我看到一个东西,才完全明白这个ActivityThread 中attach函数的真正目的:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="android" coreApp="true" android:sharedUserId="android.uid.system"    android:sharedUserLabel="@string/android_system_label">
上面这段code是AndroidManifest.xml中部分,package name是 ---> android,这下就解释通了。这里创建的Application 就是这个应用了,可以看出一个ActivityThread可以运行多个application,这里的application指的是android,而且,这个android 应用被设置为mInitialApplication。

在回头看一下LoadedApk的构造函数:

    public LoadedApk(ActivityThread activityThread, String name,            Context systemContext, ApplicationInfo info, CompatibilityInfo compatInfo) {        mActivityThread = activityThread;        mApplicationInfo = info != null ? info : new ApplicationInfo();        mApplicationInfo.packageName = name;        mPackageName = name;        mAppDir = null;        mResDir = null;        mSharedLibraries = null;        mDataDir = null;        mDataDirFile = null;        mLibDir = null;        mBaseClassLoader = null;        mSecurityViolation = false;        mIncludeCode = true;        mClassLoader = systemContext.getClassLoader();        mResources = systemContext.getResources();        mDisplayAdjustments.setCompatibilityInfo(compatInfo);    }
就是创建了android 这个application,实例化了一个ApplicationInfo,指定了mApplicationInfo.packageName,mPackageName都为android。最关键的是mClassLoader、mResources、mDisplayAdjustments。

说了半天这个android应用,也提出了他的AndroidManifest.xml,那么这个android应用到底是什么呢?bingo,就是framework-res.apk。

(5)DropBox.setReporter(new DropBoxReporter());

(6)ViewRootImpl.addConfigCallback(new ComponentCallbacks2(){});

向ViewRootImpl注册一个callback用于接收ConfigurationChanged事件(例如横竖屏切换、输入法弹出等),我们将在介绍WindowsManager的时候来分析如果dispatch这些事件到具体的activity当中。


4)通过ActivityThread分析后mSystemThread = at;这里的mSystemThread同mSelf,都是static

5)初始化AMS的mContext、mFactoryTest、mIntentFirewall、mStackSupervisor

        Context context = at.getSystemContext();        context.setTheme(android.R.style.Theme_Holo);        m.mContext = context;        m.mFactoryTest = factoryTest;        m.mIntentFirewall = new IntentFirewall(m.new IntentFirewallInterface());        m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper);        m.mBatteryStatsService.publish(context);        m.mUsageStatsService.publish(context);        m.mAppOpsService.publish(context);

主要创建IntentFirewall,而IntentFirewall/data/system/ifw/ifw.xmlor/data/secure/system/ifw/ifw.xml读取出来activitybroadcastservice,并时刻监听着文件是否改变,而IntentFirewallInterface则是看是否是ActivityManagerService的进程id而下面BatteryStatsServiceUsageStatsServiceAppOpsService.则是把服务注册掉bindermanager

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

    public final void startRunning(String pkg, String cls, String action,            String data) {        synchronized(this) {            if (mStartRunning) {                return;            }            mStartRunning = true;            mTopComponent = pkg != null && cls != null                    ? new ComponentName(pkg, cls) : null;            mTopAction = action != null ? action : Intent.ACTION_MAIN;            mTopData = data;            if (!mSystemReady) {                return;            }        }        systemReady(null);    }

因为进入startRunning时mStartRunning和mSystemReady都为false,所以这里只是设置mStartRunning为true,mTopComponent为null,mTopAction为Intent.ACTION_MAIN,mTopData为null就直接返回。

到这里ActivityManagerService.main就全部解析完成。

总结一下:

main中的AThread中创建了一个looper,然后实例化了一个AMS,也就是mSelf;接着实例化了一个static 的ActivityThread,也就是mSystemThread,在ActivityThread中实例化了Application,即framework-res.apk;接着就是一些设置,如mContext、mFactoryTest、mIntentFirewall、mStackSupervisor、mBatteryStatsService、mUsageStatsService、mAppOpsService;startRunning。




更多相关文章

  1. android 混淆配置 实例实战项目讲解
  2. Android 只开启一个Activity实例
  3. OpenCV android sdk配置OpenCV android NDK开发实例
  4. android 4.0横屏重复调用onCreate()函数
  5. AIDL实例分析和讲解
  6. Android常用实例—Alert Dialog的使用
  7. Android利用系统提供的函数或常量判断版本大小

随机推荐

  1. android 将鼠标右键点击事件改为点击后返
  2. Android中子布局填充ScrollView
  3. Android中webview跟JAVASCRIPT中的交互
  4. Android编译系统学习总结
  5. Android获取经纬度
  6. android振动效果的实现
  7. 【android】以前没有注意的一个ListActiv
  8. (转帖)Android系列之Wifi定位
  9. Android处理后台返回数据——Json转实体
  10. Android(安卓)Studio中同步代码时报:Recei