android ActivityManagerService 学习 (一)



在public class SystemServer的启动中有关init2的初始化启动new ServerThread(),并且运行该线程thr.start()


    public static final void init2() {
        Slog.i(TAG, "Entered the Android system server!");
        Thread thr = new ServerThread();
        thr.setName("android.server.ServerThread");
        thr.start();
    }


 thr.start()的运行内容如下,为内部类内容class ServerThread extends Thread 


   public void run() {
 

        Looper.prepare();

        android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);

        BinderInternal.disableBackgroundScheduling(true);
        android.os.Process.setCanSelfBackground(false);

   
        try {
            Slog.i(TAG, "Entropy Service");
            ServiceManager.addService("entropy", new EntropyService());

            Slog.i(TAG, "Power Manager");
            power = new PowerManagerService();
            ServiceManager.addService(Context.POWER_SERVICE, power);

            Slog.i(TAG, "Activity Manager");
            context = ActivityManagerService.main(factoryTest);


其中context = ActivityManagerService.main(factoryTest);这句第一次提到ActivityManagerService


    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();
        m.mContext = context;
        m.mFactoryTest = factoryTest;
        m.mMainStack = new ActivityStack(m, context, true);
        
        m.mBatteryStatsService.publish(context);
        m.mUsageStatsService.publish(context);
        
        synchronized (thr) {
            thr.mReady = true;
            thr.notifyAll();
        }

        m.startRunning(null, null, null, null);
        
        return context;
    }

    public static ActivityManagerService self() {
        return mSelf;
    }
    
    static class AThread extends Thread {
        ActivityManagerService mService;
        boolean mReady = false;

        public AThread() {
            super("ActivityManager");
        }

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

            synchronized (this) {
                while (!mReady) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                    }
                }
            }

            Looper.loop();
        }
    }


从上面看出ActivityManagerService是在AThread中被初始化,在初始化完成后,AThread中的notifyAll()唤醒之前thr.wait()的堵塞,其中AThread的变量mService存储new ActivityManagerService对象,即下面的


   static class AThread extends Thread {
        ActivityManagerService mService;
     
            ActivityManagerService m = new ActivityManagerService();

            synchronized (this) {
                mService = m;

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


        ActivityManagerService m = thr.mService;


分析main方法中剩下的几行代码,代码如下:


ActivityThread at = ActivityThread.systemMain();  
    mSystemThread = at;  
    Context context = at.getSystemContext();  
    m.mContext = context;  
    m.mFactoryTest = factoryTest;  
    m.mMainStack = new ActivityStack(m, context, true);  


其中ActivityThread at = ActivityThread.systemMain()就是new了一个AcitvityThread,并且执行attach方法,这里需要注意ActivityThread不是一个线程[public final class ActivityThread],不要被类名误导了


   public static final ActivityThread systemMain() {
        ActivityThread thread = new ActivityThread();
        thread.attach(true);
        return thread;
    }

执行thread.attach(true)


    private final void attach(boolean system) {
        sThreadLocal.set(this);
        mSystemThread = system;
        if (!system) {
            ViewRoot.addFirstDrawHandler(new Runnable() {
                public void run() {
                    ensureJitEnabled();
                }
            });
            android.ddm.DdmHandleAppName.setAppName("");
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
            }
        } 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");
            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);
            }
        }
        
        ViewRoot.addConfigCallback(new ComponentCallbacks() {
            public void onConfigurationChanged(Configuration newConfig) {
                synchronized (mPackages) {
                    // We need to apply this change to the resources
                    // immediately, because upon returning the view
                    // hierarchy will be informed about it.
                    if (applyConfigurationToResourcesLocked(newConfig)) {
                        // This actually changed the resources!  Tell
                        // everyone about it.
                        if (mPendingConfiguration == null ||
                                mPendingConfiguration.isOtherSeqNewer(newConfig)) {
                            mPendingConfiguration = newConfig;
                            
                            queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);
                        }
                    }
                }
            }
            public void onLowMemory() {
            }
        });
    }


其中先分析下面这几行代码

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

上面提到的Instrumentation就是有关注释中说明的“ an AndroidManifest.xml's”,这个好像和单元测试用例有关,我之前没有写过这个东西,如下

/**
 * Base class for implementing application instrumentation code.  When running
 * with instrumentation turned on, this class will be instantiated for you
 * before any of the application code, allowing you to monitor all of the
 * interaction the system has with the application.  An Instrumentation
 * implementation is described to the system through an AndroidManifest.xml's
 *  tag.
 */


pateo@pateo-B86N53X:/work/project/android_source/packages/apps$ grep -r "instrumentation" ./
grep: ./Stk/.git/svn: 没有那个文件或目录
grep: ./PackageInstaller/.git/svn: 没有那个文件或目录
grep: ./VoiceDialer/.git/svn: 没有那个文件或目录
./VoiceDialer/tests/AndroidManifest.xml:    
grep: ./Gallery3D/.git/svn: 没有那个文件或目录
./Gallery3D/tests/AndroidManifest.xml:    
grep: ./Mms/.git/svn: 没有那个文件或目录
./Mms/tests/src/com/android/mms/ui/ConversationListTests.java: * Various instrumentation tests for ConversationList.  
./Mms/tests/src/com/android/mms/ui/ComposeMessageActivityTests.java: * Various instrumentation tests for ComposeMessageActivity.
./Mms/tests/AndroidManifest.xml:    This declares that this app uses the instrumentation test runner targeting
./Mms/tests/AndroidManifest.xml:    

再看ContextImpl

   ContextImpl() {
        // For debug only
        //++sInstanceCount;
        mOuterContext = this;
    }

继续看ContextImpl对象第一次初始化第一次初始化init

context.init(getSystemContext().mPackageInfo, null, this);

进入此方法

    public ContextImpl getSystemContext() {
        synchronized (this) {
            if (mSystemContext == null) {
                ContextImpl context =
                    ContextImpl.createSystemContext(this);
                LoadedApk info = new LoadedApk(this, "android", context, null);
                context.init(info, null, this);
                context.getResources().updateConfiguration(
                        getConfiguration(), getDisplayMetricsLocked(false));
                mSystemContext = context;
                //Slog.i(TAG, "Created system resources " + context.getResources()
                //        + ": " + context.getResources().getConfiguration());
            }
        }
        return mSystemContext;
    }


继续看,进入ContextImpl第二次初始化init

    static ContextImpl createSystemContext(ActivityThread mainThread) {
        ContextImpl context = new ContextImpl();
        context.init(Resources.getSystem(), mainThread);
        return context;
    }

进入static Resources getSystem方法

    public static Resources getSystem() {
        synchronized (mSync) {
            Resources ret = mSystem;
            if (ret == null) {
                ret = new Resources();
                mSystem = ret;
            }

            return ret;
        }
    }

从上面代码我们可以看到,这里new 了一个Resources对象,关于上面这个方法,我们看下面注释:

  /**
     * Return a global shared Resources object that provides access to only
     * system resources (no application resources), and is not configured for 
     * the current screen (can not use dimension units, does not change based 
     * on orientation, etc). 
     */

从上面来看,返回一个全局共享资源对象只能访问系统资源,(没有应用资源),把Resources对象作为参数传入
  final void init(Resources resources, ActivityThread mainThread) {
        mPackageInfo = null;
        mResources = resources;
        mMainThread = mainThread;
        mContentResolver = new ApplicationContentResolver(this, mainThread);
    }

上面代码会发现之前的Resources对象存储到ContextImpl对象的属性mResources中了,所以以后只要通过ContextImpl对象就可以取到Resources对象了

    private Resources mResources;
    
@Override
    public Resources getResources() {
        return mResources;
    }

同时还做做了下面两步操作:

1、当前的ActivityThread对象即mainThread被存入到ContextImpl的属性mMainThread中,

2、new一个ApplicationContentResolver对象,此对象存储到ContextImpl中

    
    private ApplicationContentResolver mContentResolver;
@Override
    public ContentResolver getContentResolver() {
        return mContentResolver;
    }

进入ApplicationContentResolver类中看一下

   private static final class ApplicationContentResolver extends ContentResolver {
        public ApplicationContentResolver(Context context, ActivityThread mainThread) {
            super(context);
            mMainThread = mainThread;
        }     
        private final ActivityThread mMainThread;
    }

就这样,把当前的ActivityThread对象也存储到了ApplicationContentResolver对象的属性mMainThread中

这样ContextImpl就关联到了ApplicationContentResolver,而ApplicationContentResolver继承了ContentResolver,这样以后就可以通过ContextImpl访问到ContentResolver的共享资源,再回过来看,就是createSystemContext方法提供了通过ContextImpl来访问Resources和

ContentResolver,这个就是在ContextImpl第二次初始化init方法中实现的


现在我们回到createSystemContext方法的下一步即回到ContextImpl第二次初始化init方法的下一步

LoadedApk info = new LoadedApk(this, "android", context, null);

进入该new LoadedApk

    public LoadedApk(ActivityThread activityThread, String name,
            Context systemContext, ApplicationInfo info) {
        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();
        mCompatibilityInfo = new CompatibilityInfo(mApplicationInfo);
    }

上面我们重点看如下三行代码:

     mActivityThread = activityThread;
        mApplicationInfo = info != null ? info : new ApplicationInfo();
        mApplicationInfo.packageName = name;
   
        mResources = systemContext.getResources();
        mCompatibilityInfo = new CompatibilityInfo(mApplicationInfo);

其中

1、通过LoadedApk的属性mActivityThread来关联当前的ActivityThread,即当前对象ActivityThread被存储到LoadedApk的属性mActivityThread中

2、new 了 ApplicationInfo 被存储到LoadedApk的属性mApplicationInfo中

3、给予LoadedApk的属性mApplicationInfo为ApplicationInfo对象,并且针对该ApplicationInfo对象进行初始化ApplicationInfo对象的属性packageName值为“android”

4、把经过第二次init初始化的ContextImpl对象存储到LoadedApk的属性mResources中

5、mCompatibilityInfo = new CompatibilityInfo(mApplicationInfo);这一句,暂时性根据方法名称的意思为“兼容性信息”,这里暂时不做深入的研究


通过上面逻辑执行后,回到 new LoadedApk的下一步,即进行第三次ContextImpl的初始化init, context.init(info, null, this);进入该方法

    final void init(LoadedApk packageInfo,
            IBinder activityToken, ActivityThread mainThread) {
        init(packageInfo, activityToken, mainThread, null);
    }

    final void init(LoadedApk packageInfo,
                IBinder activityToken, ActivityThread mainThread,
                Resources container) {
        mPackageInfo = packageInfo;
        mResources = mPackageInfo.getResources(mainThread);

        if (mResources != null && container != null
                && container.getCompatibilityInfo().applicationScale !=
                        mResources.getCompatibilityInfo().applicationScale) {
            if (DEBUG) {
                Log.d(TAG, "loaded context has different scaling. Using container's" +
                        " compatiblity info:" + container.getDisplayMetrics());
            }
            mResources = mainThread.getTopLevelResources(
                    mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
        }
        mMainThread = mainThread;
        mContentResolver = new ApplicationContentResolver(this, mainThread);

        setActivityToken(activityToken);
    }

从上面代码来看,有些重复,但是有些未重复

   mMainThread = mainThread;
        mContentResolver = new ApplicationContentResolver(this, mainThread);


未重复的做重点介绍:

mPackageInfo = packageInfo;
        mResources = mPackageInfo.getResources(mainThread);

从上面看出

1、LoadedApk对象被存储到ContextImpl的属性LoadedApk中,而LoadedApk对象中之前的属性mResources存储着ContextImpl的mResources而现在通过“mPackageInfo.getResources(mainThread)”即“LoadedApk.getResources(mainThread)”,所以下面的代码就不再会走人mainThread.getTopLevelResources方法,如下:

    public Resources getResources(ActivityThread mainThread) {
        if (mResources == null) {
            mResources = mainThread.getTopLevelResources(mResDir, this);
        }
        return mResources;
    }

而之前的setActivityToken(activityToken)传入的是null,即setActivityToken(null),进入该方法发现没做什么事

    final void setActivityToken(IBinder token) {
        mActivityToken = token;
    }

回到getSystemContext方法

    public ContextImpl getSystemContext() {
        synchronized (this) {
            if (mSystemContext == null) {
                ContextImpl context =
                    ContextImpl.createSystemContext(this);
                LoadedApk info = new LoadedApk(this, "android", context, null);
                context.init(info, null, this);
                context.getResources().updateConfiguration(
                        getConfiguration(), getDisplayMetricsLocked(false));
                mSystemContext = context;
                //Slog.i(TAG, "Created system resources " + context.getResources()
                //        + ": " + context.getResources().getConfiguration());
            }
        }
        return mSystemContext;
    }

这个方法里面只有一句未分析,即:

context.getResources().updateConfiguration(
                        getConfiguration(), getDisplayMetricsLocked(false));

上面一句,涉及到WindowManager,这个暂时关系到WindowManager的先放一放,我以后这块单独学习分析

    DisplayMetrics getDisplayMetricsLocked(boolean forceUpdate) {
        if (mDisplayMetrics != null && !forceUpdate) {
            return mDisplayMetrics;
        }
        if (mDisplay == null) {
            WindowManager wm = WindowManagerImpl.getDefault();
            mDisplay = wm.getDefaultDisplay();
        }
        DisplayMetrics metrics = mDisplayMetrics = new DisplayMetrics();
        mDisplay.getMetrics(metrics);
        //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
        //        + metrics.heightPixels + " den=" + metrics.density
        //        + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi);
        return metrics;
    }

最后mSystemContext = context;回到getSystemContext的下一步,即之前attach方法中

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

我们其中有的已经分析了,现在主要分析如下:

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

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

从上面来看Application是通过反射来生成对象的,再来看app.attach(context)方法

final void attach(Context context) {
        attachBaseContext(context);
    }

这里我需要说下这个Application的继承实现关系

public class Application extends ContextWrapper implements ComponentCallbacks

所以上面的继续根中方法ContextWrapper的方法attachBaseContext

    protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }

而ContextWrapper的继承关系如下:

public class ContextWrapper extends Context
再看看这个类的注释

/**
 * Proxying implementation of Context that simply delegates all of its calls to
 * another Context.  Can be subclassed to modify behavior without changing
 * the original Context.
 */

从注释来看,它是Context的代理,而Context是我们常用的类,我们来熟悉下它的定义

/**
 * Interface to global information about an application environment.  This is
 * an abstract class whose implementation is provided by
 * the Android system.  It
 * allows access to application-specific resources and classes, as well as
 * up-calls for application-level operations such as launching activities,
 * broadcasting and receiving intents, etc.
 */

最后,之前的mContext最终赋值给了ActivityManagerService对想m的属性mContext,进行了存储,即回到了main方法中

    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();
        m.mContext = context;
        m.mFactoryTest = factoryTest;
        m.mMainStack = new ActivityStack(m, context, true);
        
        m.mBatteryStatsService.publish(context);
        m.mUsageStatsService.publish(context);
        
        synchronized (thr) {
            thr.mReady = true;
            thr.notifyAll();
        }

        m.startRunning(null, null, null, null);
        
        return context;
    }

我们接着上面未分析的 m.mMainStack = new ActivityStack(m, context, true);

ActivityStack(ActivityManagerService service, Context context, boolean mainStack) {
        mService = service;
        mContext = context;
        mMainStack = mainStack;
        PowerManager pm =
            (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        mGoingToSleep = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
        mLaunchingActivity = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ActivityManager-Launch");
        mLaunchingActivity.setReferenceCounted(false);
    }

从上面可以看出,如下信息

1、ActivityManagerService对象被存储到了ActivityStack对象的属性mService中,context被存储到ActivityStack对象的属性mContext中

2、有关获取power的服务,进行创建wakeLock

最后上面的返回的ActivityStack对象被存储到了ActivityManagerService对想m的属性mMainStack中


接下来看main方法中的最后几步



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

从上面来看未做什么事,而其中的systemReady(null)进入该方法未去执行直接返回了,分析到这里,我们基本把ServerThread中的

 context = ActivityManagerService.main(factoryTest);分析完了





















你可能感兴趣的:(Framework)