activitymanagerservice启动

ActivityManagerService(简称AMS)
ActivityManagerNative(简称AMN)
WindowManagerService(简称WMS)


*******************************************************************************************************************************************



AMS的调用轨迹
    system_server.java::ServerThread
   context = ActivityManagerService.main(factoryTest)    //1调用main函数,得到一个Context对象
ActivityManagerService.setSystemProcess();     //2setSystemProcess:这样system_server进程可加到AMS中,并被它管理
ActivityManagerService.installSystemProviders();      //3installSystemProviders:将SettingsProvider放到system_server进程中来运行
ActivityManagerService.self().setWindowManager(wm);   //4在内部保存WindowManagerService(以后简称WMS)
ActivityManagerNative.getDefault().showBootMessage(     //5和WMS交互,弹出“启动进度”对话框
                    context.getResources().getText(
                            com.android.internal.R.string.android_upgrading_starting_apps),
                            false);
ActivityManagerService.self().systemReady(new Runnable() {......}    //6AMS是系统的核心,只有它准备好了才能调用其他服务的systemReady


1、调用main函数,得到一个Context对象(ActivityManagerService.java)
   public static final Context main(int factoryTest){
            AThread thr = new AThread();   //1创建一个AThread线程对象
            thr.start();
...... //等待thr创建成功

ActivityManagerService m = thr.mService;
            mSelf = m;

//2调用ActivityThread的systemMain函数
ActivityThread at = ActivityThread.systemMain();
mSystemThread = at;

//3得到一个Context对象,注意是用的是getSystemContext
            Context context = at.getSystemContext();
            context.setTheme(android.R.style.Theme_Holo);
            m.mContext = context;
            m.mFactoryTest = factoryTest;
            
//ActivityStack是AMS中用来管理Activity的启动和调度的核心类,以后再分析它
m.mMainStack = new ActivityStack(m, context, true);
            //调用BSS的publish(第五章中讲过了)
            m.mBatteryStatsService.publish(context);
            //另一个Service
m.mUsageStatsService.publish(context);
        
            synchronized (thr) {
                thr.mReady = true;
                thr.notifyAll();    //通知thr线程,本线程工作完成
            }
            
//4调用AMS的startRunning函数
            m.startRunning(null, null, null, null);
        
            return context;
}


   说明:
            AMS自己的工作在AThread线程中做,
            main函数首先需要等待AThread所在线程启动并完成一部分工作;
AThread完成那一部分工作后,等待main函数完成后续工作。

        1.1 AThread分析
        1.1_1 AThread分析
   ActivityManagerService.java::AThread
   
static class AThread extends Thread {
......
public void run() {
......
ActivityManagerService m = new ActivityManagerService();
......

}
}
 
            AThread的主要工作就是创建AMS对象,然后通知AMS的main函数。
   1.1_2 AMS的构造函数分析
   ActivityManagerService.java::ActivityManagerService


    private ActivityManagerService() {
        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
        
        mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
        mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
        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();
        mBatteryStatsService = new BatteryStatsService(new File(
                systemDir, "batterystats.bin").toString());
        mBatteryStatsService.getActiveStatistics().readLocked();
        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
        mOnBattery = DEBUG_POWER ? true
                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
        mBatteryStatsService.getActiveStatistics().setCallback(this);
        
        mUsageStatsService = new UsageStatsService(new File(
                systemDir, "usagestats").toString());
        mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));


        // User 0 is the first and only user that runs at boot.
        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
        mUserLru.add(Integer.valueOf(0));
        updateStartedUserArrayLocked();


        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);


        mConfiguration.setToDefaults();
        mConfiguration.setLocale(Locale.getDefault());


        mConfigurationSeq = mConfiguration.seq = 1;
        mProcessStats.init();
        
        mCompatModePackages = new CompatModePackages(this, systemDir);


        // Add ourself to the Watchdog monitors.
        Watchdog.getInstance().addMonitor(this);


        mProcessStatsThread = new Thread("ProcessStats") {
            public void run() {
                while (true) {
                    try {
                        try {
                            synchronized(this) {
                                final long now = SystemClock.uptimeMillis();
                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
                                //        + ", write delay=" + nextWriteDelay);
                                if (nextWriteDelay < nextCpuDelay) {
                                    nextCpuDelay = nextWriteDelay;
                                }
                                if (nextCpuDelay > 0) {
                                    mProcessStatsMutexFree.set(true);
                                    this.wait(nextCpuDelay);
                                }
                            }
                        } catch (InterruptedException e) {
                        }
                        updateCpuStatsNow();
                    } catch (Exception e) {
                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
                    }
                }
            }
        };
        mProcessStatsThread.start();
    }



一些初始化创建等:
   a、创建BSS、USS、mProcessStats、mProcessStatsThread线程,这些都是与系统运行状况统计相关。
b、创建/data/system目录,为mCompatModePackages和mConfiguration等成员赋值。
   


1.2 ActivityThread.systemMain函数分析

   ActivityThread是Framework中一个非常重要的类,它代表一个应用进程的主线程,其职责就是调度及执行在该线程中运行的四大组件。

   public static ActivityThread systemMain() {
                HardwareRenderer.disable(true);   //禁止硬件加速
                ActivityThread thread = new ActivityThread();  //空构造函数
                thread.attach(true);
                return thread;
            }

   这里主要做了 禁止硬件加速和创建自己并调用了attach函数。


       private void attach(boolean system) {
           sThreadLocal.set(this);
           mSystemThread = system;
           if (!system) {
               //应用进程处理流程
           } else {


               android.ddm.DdmHandleAppName.setAppName("system_process",    //systemserver的进程名
                                                       UserHandle.myUserId());
               try {
                   mInstrumentation = new Instrumentation();   //Instrumentation 工具类
                   ContextImpl context = new ContextImpl();    //
                   context.init(getSystemContext().mPackageInfo, null, this);    //为什么getSystemContext
                   Application app = Instrumentation.newApplication(Application.class, context);   //利用Instrumentation创建Application
                   mAllApplications.add(app);
                   mInitialApplication = app;
                   app.onCreate();   //调用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() {
               public void onConfigurationChanged(Configuration newConfig) {
                     //当系统配置发生变化时调用(如语言切换)
               }
               public void onLowMemory() {}
               public void onTrimMemory(int level) {}
           });
       }
                
            attach函数中几个重要成员的作用:
            a、Instrumentation:当app被启用时先创建Instrumentation,然后通过它来创建其他组件,系统和组件之间的交互也通过Instrumentation来传递。Instrumentation 能监控这些交互情况。
b、Application:Application保存了一个全局的Application状态。
c、Context:Context是一个接口,通过它可以获取并操作Application的资源、类及Application的四大组件。

            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);   //LoadedApk代表一个加载到系统的apk
                       context.init(info, null, this);    //初始化ContextImpl对象
                       context.getResources().updateConfiguration(     //初始化资源信息
                                getConfiguration(), getDisplayMetricsLocked(
                                        Display.DEFAULT_DISPLAY,
                                        CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO));
                       mSystemContext = context;      //保存
                       //Slog.i(TAG, "Created system resources " + context.getResources()
                        //        + ": " + context.getResources().getConfiguration());
                   }
               }
               return mSystemContext;
            }
  
以上代码先创建一个ContextImpl,然后初始化,使用getSystemContext命名因为其要加载的是framework-res.apk,此apk的package名为“android”,仅供system_server使用。

systemMain总结:
   a、得到一个ActivityThread对象,代表应用进程主线程
b、得到Context对象,指向其运行环境。使得system_server<==>AMS
        
1.3 AMS的startrunning函数:
            
ActivityManagerService.java::startrunning

   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);    //重要  后续说明
    }


        ActivityManagerService的main总结:
   a、创建AMS
b、为system_server配置android运行环境

2、AMS的setSystemProcess
   ActivityManagerService.java::setSystemProcess

     public static void setSystemProcess() {
         try {
             ActivityManagerService m = mSelf;
                //向ServiceManager注册几个服务
             ServiceManager.addService("activity", m, true);
             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));    //向SM注册权限管理服务


             ApplicationInfo info =      //使用AMS的mContext对象
                 mSelf.mContext.getPackageManager().getApplicationInfo(
                             "android", STOCK_PM_FLAGS);
             mSystemThread.installSystemApplicationInfo(info);     //调用ystemThread的installSystemApplicationInfo函数
       
             synchronized (mSelf) {
                 ProcessRecord app = mSelf.newProcessRecordLocked(      //AMS对进程的管理
                         mSystemThread.getApplicationThread(), info,
                         info.processName, false);
                 app.persistent = true;
                 app.pid = MY_PID;
                 app.maxAdj = ProcessList.SYSTEM_ADJ;
                 mSelf.mProcessNames.put(app.processName, app.uid, app);
                 synchronized (mSelf.mPidsSelfLocked) {
                     mSelf.mPidsSelfLocked.put(app.pid, app);
                 }
                  mSelf.updateLruProcessLocked(app, true);
              }
          } catch (PackageManager.NameNotFoundException e) {
              throw new RuntimeException(
                     "Unable to find android system package", e);
          }
      }




        2.1 installSystemApplicationInfo

ActivityThread.java::installSystemApplicationInfo

public void installSystemApplicationInfo(ApplicationInfo info) {
            synchronized (this) {
                ContextImpl context = getSystemContext();
                context.init(new LoadedApk(this, "android", context, info,      //此次真正给context设置info
                        CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO), null, this);


                // give ourselves a default profiler  //用于性能统计
                mProfiler = new Profiler();
            }
        }

插入说明5

IApplicationThread仅仅是AMS和另一个进程交互的接口,AMS还需要该进程的信息,用ProcessRecord数据结构来保存进程信息。
        ActivityManagerService.java::newProcessRecordLocked

    final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
            ApplicationInfo info, String customProcess, boolean isolated) {
        String proc = customProcess != null ? customProcess : info.processName;
        BatteryStatsImpl.Uid.Proc ps = null;
        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
        int uid = info.uid;
        if (isolated) {
            int userId = UserHandle.getUserId(uid);
            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
            uid = 0;
            while (true) {
                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
                }
                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
                mNextIsolatedProcessUid++;
                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
                    // No process for this uid, use it.
                    break;
                }
                stepsLeft--;
                if (stepsLeft <= 0) {
                    return null;
                }
            }
        }
        synchronized (stats) {
            ps = stats.getProcessStatsLocked(info.uid, proc);
        }
        return new ProcessRecord(ps, thread, info, proc, uid);
    }


   看看构造函数:
ProcessRecord.java::ProcessRecord

    ProcessRecord(BatteryStatsImpl.Uid.Proc _batteryStats, IApplicationThread _thread,
            ApplicationInfo _info, String _processName, int _uid) {
        batteryStats = _batteryStats;
        info = _info;    //保存最开始启动的ApplicationInfo
        isolated = _info.uid != _uid;
        uid = _uid;
        userId = UserHandle.getUserId(_uid);
        processName = _processName;    //system_process
        pkgList.add(_info.packageName);   //
        thread = _thread;
        maxAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
        hiddenAdj = clientHiddenAdj = emptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
        curRawAdj = setRawAdj = -100;
        curAdj = setAdj = -100;
        persistent = false;
        removed = false;
    }


在上述ActivityManagerService.java::setSystemProcess 中还设置了:
                 app.persistent = true;
                 app.pid = MY_PID;
                 app.maxAdj = ProcessList.SYSTEM_ADJ;

至此system_srver的ProcessRecord创建完成。AMS中有两个成员变量来保存ProcessRecord,mProcessNames和mPidsSelfLocked(各自用途情况???)

   AMS的setSystemProcess总结:
            a、注册AMS,meminfo,gfxinfo等服务到SM
            b、根据PKMS返回的ApplicationInfo初始化system_server的android运行环境。



3. AMS的installSystemProviders分析
   installSystemProviders加载的是SettingsProvider.apk,并把它放在system_server进程中来运行。
   ActivityManagerService.java::installSystemProviders

    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); //监视long_press_timeout配置的变化


        mSelf.mUsageStatsService.monitorPackages();
    }

上述代码中有两个关键调用:
            a、调用 generateApplicationProvidersLocked 返回ProviderInfo List
b、调用 installSystemProviders ,为system_server进程安装contextProvider。


2.1 generateApplicationProvidersLocked
ActivityManagerService.java::generateApplicationProvidersLocked

    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
        List<ProviderInfo> providers = null;
        try {
            providers = AppGlobals.getPackageManager().     //想PKMS查询满足条件的ProviderInfo
                queryContentProviders(app.processName, app.uid,
                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
        } catch (RemoteException ex) {
        }
        if (DEBUG_MU)
            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
        int userId = app.userId;
        if (providers != null) {
            int N = providers.size();
            for (int i=0; i<N; i++) {      //AMS对ContextProvider的管理
                ProviderInfo cpi =
                    (ProviderInfo)providers.get(i);
                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
                        cpi.name, cpi.flags);
                if (singleton && UserHandle.getUserId(app.uid) != 0) {
                    // This is a singleton provider, but a user besides the
                    // default user is asking to initialize a process it runs
                    // in...  well, no, it doesn't actually run in this process,
                    // it runs in the process of the default user.  Get rid of it.
                    providers.remove(i);
                    N--;
                    continue;
                }


                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
                if (cpr == null) {
                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
                    mProviderMap.putProviderByClass(comp, cpr);
                }
                if (DEBUG_MU)
                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
                app.pubProviders.put(cpi.name, cpr);
                app.addPackage(cpi.applicationInfo.packageName);
                ensurePackageDexOpt(cpi.applicationInfo.packageName);
            }
        }
        return providers;
    }

generateApplicationProvidersLocked 先从PKMS中查到满足条件的ProviderInfo信息,然后分别保存到ProcessRecord( app)和AMS(mProviderMap)中。

2.1_1 queryContentProviders 查询


    public List<ProviderInfo> queryContentProviders(String processName,
            int uid, int flags) {
        ArrayList<ProviderInfo> finalList = null;


        // reader
        synchronized (mPackages) {
            final Iterator<PackageParser.Provider> i = mProvidersByComponent.values().iterator();
            final int userId = processName != null ?
                    UserHandle.getUserId(uid) : UserHandle.getCallingUserId();
            while (i.hasNext()) {
                final PackageParser.Provider p = i.next();
                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
                if (ps != null && p.info.authority != null
                        && (processName == null
                                || (p.info.processName.equals(processName)
                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
                        && mSettings.isEnabledLPr(p.info, flags, userId)
                        && (!mSafeMode
                                || (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
                    if (finalList == null) {
                        finalList = new ArrayList<ProviderInfo>(3);
                    }
                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
                            ps.readUserState(userId), userId);
                    if (info != null) {
                        finalList.add(info);
                    }
                }
            }
        }


        if (finalList != null) {
            Collections.sort(finalList, mProviderInitOrderSorter);
        }


        return finalList;
    }

queryContentProviders为什么能找到SettingsProvider呢?
因为:SettingsProvider的Manifest.xml中设置了uid为system_server,process名为system。

2.1_2 ContentProvider


        前面queryContentProviders查找到的ProviderInfo信息只是保存起来了,还需要将其与AMS和ProcessRecord联系起来
   a、AMS保存的原因就是为了管理
b、ProcessRecord保存是ProviderInfo要与一个进程联系起来,以便方便AMS管理。

图:《ContentProvideRecord团队》

2.2 ActivityThread的installSystemProviders函数
   ActivityThread.java::installSystemProviders  -------> installContentProviders


    private void installContentProviders(
            Context context, List<ProviderInfo> providers) {
        final ArrayList<IActivityManager.ContentProviderHolder> results =
            new ArrayList<IActivityManager.ContentProviderHolder>();


        for (ProviderInfo cpi : providers) {
            if (DEBUG_PROVIDER) {
                StringBuilder buf = new StringBuilder(128);
                buf.append("Pub ");
                buf.append(cpi.authority);
                buf.append(": ");
                buf.append(cpi.name);
                Log.i(TAG, buf.toString());
            }
            IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
                    false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
            if (cph != null) {
                cph.noReleaseNeeded = true;
                results.add(cph);
            }
        }


        try {
            ActivityManagerNative.getDefault().publishContentProviders(
                getApplicationThread(), results);
        } catch (RemoteException ex) {
        }
    }

installContentProviders实际上是标准的ContentProvider安装时调用的程序
其包括两个方面的工作:
     a、先在ActivityThread通过installProvider得到一个ContentProvider实例
b、向AMS发布这个ContentProvider实例(类似于向AMS注册这个实例)。


2.2_1 ActivityThread的installProvider函数
ActivityThread.java::installProvider 

    private IActivityManager.ContentProviderHolder installProvider(Context context,
            IActivityManager.ContentProviderHolder holder, ProviderInfo info,
            boolean noisy, boolean noReleaseNeeded, boolean stable) {
        ContentProvider localProvider = null;
        IContentProvider provider;
        if (holder == null || holder.provider == null) {
            if (DEBUG_PROVIDER || noisy) {
                Slog.d(TAG, "Loading provider " + info.authority + ": "
                        + info.name);
            }
            Context c = null;
            ApplicationInfo ai = info.applicationInfo;
            if (context.getPackageName().equals(ai.packageName)) {
                c = context;
            } else if (mInitialApplication != null &&
                    mInitialApplication.getPackageName().equals(ai.packageName)) {
                c = mInitialApplication;
            } else {
                try {
                    c = context.createPackageContext(ai.packageName,
                            Context.CONTEXT_INCLUDE_CODE);
                } catch (PackageManager.NameNotFoundException e) {
                    // Ignore
                }
            }
            if (c == null) {
                Slog.w(TAG, "Unable to get context for package " +
                      ai.packageName +
                      " while loading content provider " +
                      info.name);
                return null;
            }
            try {
                final java.lang.ClassLoader cl = c.getClassLoader();
                localProvider = (ContentProvider)cl.
                    loadClass(info.name).newInstance();
                provider = localProvider.getIContentProvider();
                if (provider == null) {
                    Slog.e(TAG, "Failed to instantiate class " +
                          info.name + " from sourceDir " +
                          info.applicationInfo.sourceDir);
                    return null;
                }
                if (DEBUG_PROVIDER) Slog.v(
                    TAG, "Instantiating local provider " + info.name);
                // XXX Need to create the correct context for this provider.
                localProvider.attachInfo(c, info);
            } catch (java.lang.Exception e) {
                if (!mInstrumentation.onException(null, e)) {
                    throw new RuntimeException(
                            "Unable to get provider " + info.name
                            + ": " + e.toString(), e);
                }
                return null;
            }
        } else {
            provider = holder.provider;
            if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
                    + info.name);
        }


        IActivityManager.ContentProviderHolder retHolder;


        synchronized (mProviderMap) {
            if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
                    + " / " + info.name);
            IBinder jBinder = provider.asBinder();
            if (localProvider != null) {
                ComponentName cname = new ComponentName(info.packageName, info.name);
                ProviderClientRecord pr = mLocalProvidersByName.get(cname);
                if (pr != null) {
                    if (DEBUG_PROVIDER) {
                        Slog.v(TAG, "installProvider: lost the race, "
                                + "using existing local provider");
                    }
                    provider = pr.mProvider;
                } else {
                    holder = new IActivityManager.ContentProviderHolder(info);
                    holder.provider = provider;
                    holder.noReleaseNeeded = true;
                    pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
                    mLocalProviders.put(jBinder, pr);
                    mLocalProvidersByName.put(cname, pr);
                }
                retHolder = pr.mHolder;
            } else {
                ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
                if (prc != null) {
                    if (DEBUG_PROVIDER) {
                        Slog.v(TAG, "installProvider: lost the race, updating ref count");
                    }
                    // We need to transfer our new reference to the existing
                    // ref count, releasing the old one...  but only if
                    // release is needed (that is, it is not running in the
                    // system process).
                    if (!noReleaseNeeded) {
                        incProviderRefLocked(prc, stable);
                        try {
                            ActivityManagerNative.getDefault().removeContentProvider(
                                    holder.connection, stable);
                        } catch (RemoteException e) {
                            //do nothing content provider object is dead any way
                        }
                    }
                } else {
                    ProviderClientRecord client = installProviderAuthoritiesLocked(
                            provider, localProvider, holder);
                    if (noReleaseNeeded) {
                        prc = new ProviderRefCount(holder, client, 1000, 1000);
                    } else {
                        prc = stable
                                ? new ProviderRefCount(holder, client, 1, 0)
                                : new ProviderRefCount(holder, client, 0, 1);
                    }
                    mProviderRefCountMap.put(jBinder, prc);
                }
                retHolder = prc.holder;
            }
        }


        return retHolder;
    }
        以上代码是创建 SettingsProvider
        存储情况具体如图:
a、ContentProvider是个容器,ContentProvider通过getIContentProvider获取mTransport,mTransport实现对跨进程调用的支持
b、ApplicationThreadNative从binder派生,实现了IContentProvider接口
c、ProviderClientRecord是用来保存ContentProvider信息的结构体,mLocalProviders保存ContentProvider对象,mProvider保存IContentProvider对象。
创建完成后将发布(把数据和运行环境联系起来)

2.2_2 AMS的publishContentProviders函数(发布前面创建的provider)
ActivityManagerService.java::publishContentProviders

    public final void publishContentProviders(IApplicationThread caller,
            List<ContentProviderHolder> providers) {
        if (providers == null) {
            return;
        }


        enforceNotIsolatedCaller("publishContentProviders");
        synchronized (this) {
            final ProcessRecord r = getRecordForAppLocked(caller);
            if (DEBUG_MU)
                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
            if (r == null) {
                throw new SecurityException(
                        "Unable to find app for caller " + caller
                      + " (pid=" + Binder.getCallingPid()
                      + ") when publishing content providers");
            }


            final long origId = Binder.clearCallingIdentity();


            final int N = providers.size();
            for (int i=0; i<N; i++) {
                ContentProviderHolder src = providers.get(i);
                if (src == null || src.info == null || src.provider == null) {
                    continue;
                }
                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
                if (DEBUG_MU)
                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
                if (dst != null) {
                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
                    mProviderMap.putProviderByClass(comp, dst);
                    String names[] = dst.info.authority.split(";");
                    for (int j = 0; j < names.length; j++) {
                        mProviderMap.putProviderByName(names[j], dst);
                    }


                    int NL = mLaunchingProviders.size();    
                    int j;
                    for (j=0; j<NL; j++) {
                        if (mLaunchingProviders.get(j) == dst) {
                            mLaunchingProviders.remove(j);
                            j--;
                            NL--;
                        }
                    }
                    synchronized (dst) {
                        dst.provider = src.provider;
                        dst.proc = r;
                        dst.notifyAll();
                    }
                    updateOomAdjLocked(r);   //发布一个Provider
                }
            }


            Binder.restoreCallingIdentity(origId);
        }
    }

大概梳理一下:publishContentProviders:

   a、 先根据调用者的PID找到对应的ProcessRecord对象。
   b、 这个ProcessRecord的pubProviders中保存了ContentProviderRecord信息。在generateApplicationProvidersLocked函数生成。
   c、 判断ContentProvider是否由那个package声明,返回成功,则将对应的authority加到mProviderMap中。
d、mLaunchingProviders和dst.notifyAl用于通知那些等待ContentProvider所在进程启动的客户端进程。

至此SettingsProvider正式加入到了AMS,之后和Settings数据库相关的操作均由它来管理。

4. AMS的systemReady分析 (ActivityManagerService.self().systemReady)
***********************
第一阶段
*****************************************************************************************************************************************
    public void systemReady(final Runnable goingCallback) {
        synchronized(this) {
            if (mSystemReady) {
                if (goingCallback != null) goingCallback.run();
                return;
            }
            
            // Check to see if there are any update receivers to run.
            if (!mDidUpdate) {
                if (mWaitingUpdate) {
                    return;
                }
                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
                List<ResolveInfo> ris = null;
                try {
                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
                            intent, null, 0, 0);
                } catch (RemoteException e) {
                }
                if (ris != null) {
                    for (int i=ris.size()-1; i>=0; i--) {
                        if ((ris.get(i).activityInfo.applicationInfo.flags
                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
                            ris.remove(i);
                        }
                    }
                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);


                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();


                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
                    for (int i=0; i<ris.size(); i++) {
                        ActivityInfo ai = ris.get(i).activityInfo;
                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
                        if (lastDoneReceivers.contains(comp)) {
                            ris.remove(i);
                            i--;
                        }
                    }


                    final int[] users = getUsersLocked();
                    for (int i=0; i<ris.size(); i++) {
                        ActivityInfo ai = ris.get(i).activityInfo;
                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
                        doneReceivers.add(comp);
                        intent.setComponent(comp);
                        for (int j=0; j<users.length; j++) {
                            IIntentReceiver finisher = null;
                            if (i == ris.size()-1 && j == users.length-1) {
                                finisher = new IIntentReceiver.Stub() {
                                    public void performReceive(Intent intent, int resultCode,
                                            String data, Bundle extras, boolean ordered,
                                            boolean sticky, int sendingUser) {
                                        // The raw IIntentReceiver interface is called
                                        // with the AM lock held, so redispatch to
                                        // execute our code without the lock.
                                        mHandler.post(new Runnable() {
                                            public void run() {
                                                synchronized (ActivityManagerService.this) {
                                                    mDidUpdate = true;
                                                }
                                                writeLastDonePreBootReceivers(doneReceivers);
                                                showBootMessage(mContext.getText(
                                                        R.string.android_upgrading_complete),
                                                        false);
                                                systemReady(goingCallback);
                                            }
                                        });
                                    }
                                };
                            }
                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
                                    + " for user " + users[j]);
                            broadcastIntentLocked(null, null, intent, null, finisher,
                                    0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
                                    users[j]);
                            if (finisher != null) {
                                mWaitingUpdate = true;
                            }
                        }
                    }
                }
                if (mWaitingUpdate) {
                    return;
                }
                mDidUpdate = true;
            }
            
            mSystemReady = true;
            if (!mStartRunning) {
                return;
            }
        }
*****************************************************************************************************************************************
由以上代码可知,systemReady第一个阶段的工作主要是发送并处理与PRE_BOOT_COMPLETED广播相关的事情。



***********************
第二阶段
*****************************************************************************************************************************************
        ArrayList<ProcessRecord> procsToKill = null;
        synchronized(mPidsSelfLocked) {
            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
                if (!isAllowedWhileBooting(proc.info)){
                    if (procsToKill == null) {
                        procsToKill = new ArrayList<ProcessRecord>();
                    }
                    procsToKill.add(proc);
                }
            }
        }
        
        synchronized(this) {
            if (procsToKill != null) {
                for (int i=procsToKill.size()-1; i>=0; i--) {
                    ProcessRecord proc = procsToKill.get(i);
                    Slog.i(TAG, "Removing system update proc: " + proc);
                    removeProcessLocked(proc, true, false, "system update done");
                }
            }
            
            // Now that we have cleaned up any update processes, we
            // are ready to start launching real processes and know that
            // we won't trample on them any more.
            mProcessesReady = true;
        }
        
        Slog.i(TAG, "System now ready");
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
            SystemClock.uptimeMillis());


        synchronized(this) {
            // Make sure we have no pre-ready processes sitting around.
            
            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
                ResolveInfo ri = mContext.getPackageManager()
                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
                                STOCK_PM_FLAGS);
                CharSequence errorMsg = null;
                if (ri != null) {
                    ActivityInfo ai = ri.activityInfo;
                    ApplicationInfo app = ai.applicationInfo;
                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
                        mTopAction = Intent.ACTION_FACTORY_TEST;
                        mTopData = null;
                        mTopComponent = new ComponentName(app.packageName,
                                ai.name);
                    } else {
                        errorMsg = mContext.getResources().getText(
                                com.android.internal.R.string.factorytest_not_system);
                    }
                } else {
                    errorMsg = mContext.getResources().getText(
                            com.android.internal.R.string.factorytest_no_action);
                }
                if (errorMsg != null) {
                    mTopAction = null;
                    mTopData = null;
                    mTopComponent = null;
                    Message msg = Message.obtain();
                    msg.what = SHOW_FACTORY_ERROR_MSG;
                    msg.getData().putCharSequence("msg", errorMsg);
                    mHandler.sendMessage(msg);
                }
            }
        }


        retrieveSettings();
*****************************************************************************************************************************************
        systemReady第二阶段:
   a、杀死在AMS未启动完毕就先启动的应用进程(java进程)。
b、从Settings数据库中获取配置信息,配置:debug_app,wait_for_debugger,always_finish_activityes,font_scale(字体放大倍数)。








***********************
第三阶段
*****************************************************************************************************************************************
        if (goingCallback != null) goingCallback.run();
        
        synchronized (this) {
            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
                try {
                    List apps = AppGlobals.getPackageManager().
                        getPersistentApplications(STOCK_PM_FLAGS);
                    if (apps != null) {
                        int N = apps.size();
                        int i;
                        for (i=0; i<N; i++) {
                            ApplicationInfo info
                                = (ApplicationInfo)apps.get(i);
                            if (info != null &&
                                    !info.packageName.equals("android")) {     //android<===>framework-res.apk
                                addAppLocked(info, false);  //启动该application所在进程。
                            }
                        }
                    }
                } catch (RemoteException ex) {
                    // pm is in same process, this will never happen.
                }
            }


            // Start up initial activity.
            mBooting = true;
            
            try {
                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
                    Message msg = Message.obtain();
                    msg.what = SHOW_UID_ERROR_MSG;
                    mHandler.sendMessage(msg);
                }
            } catch (RemoteException e) {
            }


            long ident = Binder.clearCallingIdentity();
            try {
                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                        | Intent.FLAG_RECEIVER_FOREGROUND);
                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
                broadcastIntentLocked(null, null, intent,
                        null, null, 0, null, null, null,
                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
                intent = new Intent(Intent.ACTION_USER_STARTING);
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
                broadcastIntentLocked(null, null, intent,
                        null, new IIntentReceiver.Stub() {
                            @Override
                            public void performReceive(Intent intent, int resultCode, String data,
                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
                                    throws RemoteException {
                            }
                        }, 0, null, null,
                        android.Manifest.permission.INTERACT_ACROSS_USERS,
                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
            mMainStack.resumeTopActivityLocked(null);
            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
        }
    }
*****************************************************************************************************************************************

   systemReady第三阶段:
   a、调用systemReady设置的回调对象goingCallback的run函数
b、启动那些声明了persistent的APK
c、启动桌面




   4.1 回调:(回调是在SystemServer.java 中定义的)
        ActivityManagerService.self().systemReady(new Runnable() {
            public void run() {
                Slog.i(TAG, "Making services ready");


                if (!headless) startSystemUi(contextF);
                try {
                    if (mountServiceF != null) mountServiceF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Mount Service ready", e);
                }
                try {
                    if (batteryF != null) batteryF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Battery Service ready", e);
                }
                try {
                    if (networkManagementF != null) networkManagementF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Network Managment Service ready", e);
                }
                try {
                    if (networkStatsF != null) networkStatsF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Network Stats Service ready", e);
                }
                try {
                    if (networkPolicyF != null) networkPolicyF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Network Policy Service ready", e);
                }
                try {
                    if (connectivityF != null) connectivityF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Connectivity Service ready", e);
                }
                try {
                    if (dockF != null) dockF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Dock Service ready", e);
                }
                try {
                    if (usbF != null) usbF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making USB Service ready", e);
                }
                try {
                    if (twilightF != null) twilightF.systemReady();
                } catch (Throwable e) {
                    reportWtf("makin Twilight Service ready", e);
                }
                try {
                    if (uiModeF != null) uiModeF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making UI Mode Service ready", e);
                }
                try {
                    if (recognitionF != null) recognitionF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Recognition Service ready", e);
                }
                Watchdog.getInstance().start();


                // It is now okay to let the various system services start their
                // third party code...


                try {
                    if (appWidgetF != null) appWidgetF.systemReady(safeMode);
                } catch (Throwable e) {
                    reportWtf("making App Widget Service ready", e);
                }
                try {
                    if (wallpaperF != null) wallpaperF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Wallpaper Service ready", e);
                }
                try {
                    if (immF != null) immF.systemReady(statusBarF);
                } catch (Throwable e) {
                    reportWtf("making Input Method Service ready", e);
                }
                try {
                    if (locationF != null) locationF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Location Service ready", e);
                }
                try {
                    if (countryDetectorF != null) countryDetectorF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Country Detector Service ready", e);
                }
                try {
                    if (throttleF != null) throttleF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Throttle Service ready", e);
                }
                try {
                    if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Network Time Service ready", e);
                }
                try {
                    if (commonTimeMgmtServiceF != null) commonTimeMgmtServiceF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Common time management service ready", e);
                }
                try {
                    if (textServiceManagerServiceF != null) textServiceManagerServiceF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Text Services Manager Service ready", e);
                }
                try {
                    if (dreamyF != null) dreamyF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making DreamManagerService ready", e);
                }
                try {
                    // TODO(BT) Pass parameter to input manager
                    if (inputManagerF != null) inputManagerF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making InputManagerService ready", e);
                }
                try {
                    if (telephonyRegistryF != null) telephonyRegistryF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making TelephonyRegistry ready", e);
                }
            }
        });


        // For debug builds, log event loop stalls to dropbox for analysis.
        if (StrictMode.conditionallyEnableDebugLogging()) {
            Slog.i(TAG, "Enabled StrictMode for system server main thread.");
        }


        Looper.loop();
        Slog.d(TAG, "System ServerThread is exiting!");
    }
   
    static final void startSystemUi(Context context) {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.android.systemui",
                    "com.android.systemui.SystemUIService"));
        //Slog.d(TAG, "Starting service: " + intent);
        context.startServiceAsUser(intent, UserHandle.OWNER);
    }
   run函数:
   a、 执行startSystemUi,对应SystemUI.apk   状态栏
   b、 调用一些其他服务的systemReady
   c、 启动Watchdog

   4.2 启动桌面
   mMainStack.resumeTopActivityLocked(null);

    final boolean resumeTopActivityLocked(ActivityRecord prev) {
        return resumeTopActivityLocked(prev, null);
    }


    final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
        // Find the first activity that is not finishing.
        ActivityRecord next = topRunningActivityLocked(null);


        // Remember how we'll process this pause/resume situation, and ensure
        // that the state is reset however we wind up proceeding.
        final boolean userLeaving = mUserLeaving;
        mUserLeaving = false;


        if (next == null) {
            // There are no more activities!  Let's just start up the
            // Launcher...
            if (mMainStack) {
                ActivityOptions.abort(options);
                return mService.startHomeActivityLocked(mCurrentUser);
            }
        }
        ......
   
        if (mResumedActivity != null) {
            if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: need to start pausing");
            // At this point we want to put the upcoming activity's process
            // at the top of the LRU list, since we know we will be needing it
            // very soon and it would be a waste to let it get killed if it
            // happens to be sitting towards the end.
            if (next.app != null && next.app.thread != null) {
                // No reason to do full oom adj update here; we'll let that
                // happen whenever it needs to later.
                mService.updateLruProcessLocked(next.app, false);
            }
            startPausingLocked(userLeaving, false);
            return true;
        }
......



   这个函数很长,这里主要关注mService.startHomeActivityLocked(mCurrentUser)

        ActivityManagerService mService;

   boolean startHomeActivityLocked(int userId) {
        if (mHeadless) {
            // Added because none of the other calls to ensureBootCompleted seem to fire
            // when running headless.
            ensureBootCompleted();
            return false;
        }


        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
                && mTopAction == null) {
            // We are running in factory test mode, but unable to find
            // the factory test app, so just sit around displaying the
            // error message and don't try to start anything.
            return false;
        }

        Intent intent = new Intent(
            mTopAction,
            mTopData != null ? Uri.parse(mTopData) : null);
        intent.setComponent(mTopComponent);
        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
            intent.addCategory(Intent.CATEGORY_HOME);
        }
ActivityInfo aInfo =
            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
        if (aInfo != null) {
            intent.setComponent(new ComponentName(
                    aInfo.applicationInfo.packageName, aInfo.name));
            // Don't do this if the home app is currently being
            // instrumented.
            aInfo = new ActivityInfo(aInfo);
            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
                    aInfo.applicationInfo.uid);
            if (app == null || app.instrumentationClass == null) {
                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                mMainStack.startActivityLocked(null, intent, null, aInfo,
                        null, null, 0, 0, 0, 0, null, false, null);
            }
        }


        return true;
    }

这个函数的位置就是添加开机记忆功能的位置(在这里读取系统属性,根据属性来决定启动网格UI还是启动TV)

    private final void startActivityLocked(ActivityRecord r, boolean newTask,
            boolean doResume, boolean keepCurTransition, Bundle options) {......}

这个函数就是根据参数具体启动应用。

   4.3 发送广播

   resumeTopActivityLocked 函数中 startHomeActivityLocked 完了之后会调用 startPausingLocked 函数

    private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
        if (mPausingActivity != null) {
            RuntimeException e = new RuntimeException();
            Slog.e(TAG, "Trying to pause when pause is already pending for "
                  + mPausingActivity, e);
        }
        ActivityRecord prev = mResumedActivity;
        if (prev == null) {
            RuntimeException e = new RuntimeException();
            Slog.e(TAG, "Trying to pause when nothing is resumed", e);
            resumeTopActivityLocked(null);
            return;
        }
        mResumedActivity = null;
        mPausingActivity = prev;
        mLastPausedActivity = prev;
        prev.state = ActivityState.PAUSING;
        prev.task.touchActiveTime();
        prev.updateThumbnail(screenshotActivities(prev), null);


        mService.updateCpuStats();
        
        if (prev.app != null && prev.app.thread != null) {
            if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);
            try {
                EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
                        prev.userId, System.identityHashCode(prev),
                        prev.shortComponentName);
                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags);
                if (mMainStack) {
                    mService.updateUsageStats(prev, false);
                }
            } catch (Exception e) {
                // Ignore exception, if process died other code will cleanup.
                Slog.w(TAG, "Exception thrown during pause", e);
                mPausingActivity = null;
                mLastPausedActivity = null;
            }
        } else {
            mPausingActivity = null;
            mLastPausedActivity = null;
        }


        // If we are not going to sleep, we want to ensure the device is
        // awake until the next activity is started.
        if (!mService.mSleeping && !mService.mShuttingDown) {
            mLaunchingActivity.acquire();
            if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
                // To be safe, don't allow the wake lock to be held for too long.
                Message msg = mHandler.obtainMessage(LAUNCH_TIMEOUT_MSG);
                mHandler.sendMessageDelayed(msg, LAUNCH_TIMEOUT);
            }
        }




        if (mPausingActivity != null) {
            // Have the window manager pause its key dispatching until the new
            // activity has started.  If we're pausing the activity just because
            // the screen is being turned off and the UI is sleeping, don't interrupt
            // key dispatch; the same activity will pick it up again on wakeup.
            if (!uiSleeping) {
                prev.pauseKeyDispatchingLocked();
            } else {
                if (DEBUG_PAUSE) Slog.v(TAG, "Key dispatch not paused for screen off");
            }


            // Schedule a pause timeout in case the app doesn't respond.
            // We don't give it much time because this directly impacts the
            // responsiveness seen by the user.
            Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
            msg.obj = prev;
            prev.pauseTime = SystemClock.uptimeMillis();
            mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
            if (DEBUG_PAUSE) Slog.v(TAG, "Waiting for pause to complete...");
        } else {
            // This activity failed to schedule the
            // pause, so just treat it as being paused now.
            if (DEBUG_PAUSE) Slog.v(TAG, "Activity not running, resuming next.");
            resumeTopActivityLocked(null);
        }
    }

   调用了schedulePauseActivity
   
        public final void schedulePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges) {
            queueOrSendMessage(
                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                    token,
                    (userLeaving ? 1 : 0),
                    configChanges);
        }    

此函数发送了PAUSE_ACTIVITY_FINISHING广播,这个广播在handleMessage中处理:

        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case PAUSE_ACTIVITY_FINISHING:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                    handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;


        handlePauseActivity来响应:

    private void handlePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges) {
        ActivityClientRecord r = mActivities.get(token);
        if (r != null) {
            //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
            if (userLeaving) {
                performUserLeavingActivity(r);
            }


            r.activity.mConfigChangeFlags |= configChanges;
            performPauseActivity(token, finished, r.isPreHoneycomb());


            // Make sure any pending writes are now committed.
            if (r.isPreHoneycomb()) {
                QueuedWork.waitToFinish();
            }


            // Tell the activity manager we have paused.
            try {
                ActivityManagerNative.getDefault().activityPaused(token);
            } catch (RemoteException ex) {
            }
        }
    }
        


        中间调用了: performPauseActivity

    final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
            boolean saveState) {
        if (r.paused) {
            if (r.activity.mFinished) {
                // If we are finishing, we won't call onResume() in certain cases.
                // So here we likewise don't want to call onPause() if the activity
                // isn't resumed.
                return null;
            }
            RuntimeException e = new RuntimeException(
                    "Performing pause of activity that is not resumed: "
                    + r.intent.getComponent().toShortString());
            Slog.e(TAG, e.getMessage(), e);
        }
        Bundle state = null;
        if (finished) {
            r.activity.mFinished = true;
        }
        try {
            // Next have the activity save its current state and managed dialogs...
            if (!r.activity.mFinished && saveState) {
                state = new Bundle();
                state.setAllowFds(false);
                mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
                r.state = state;
            }
            // Now we are idle.
            r.activity.mCalled = false;
            mInstrumentation.callActivityOnPause(r.activity);
            EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
                    r.activity.getComponentName().getClassName());
            if (!r.activity.mCalled) {
                throw new SuperNotCalledException(
                    "Activity " + r.intent.getComponent().toShortString() +
                    " did not call through to super.onPause()");
            }


        } catch (SuperNotCalledException e) {
            throw e;


        } catch (Exception e) {
            if (!mInstrumentation.onException(r.activity, e)) {
                throw new RuntimeException(
                        "Unable to pause activity "
                        + r.intent.getComponent().toShortString()
                        + ": " + e.toString(), e);
            }
        }
        r.paused = true;


        // Notify any outstanding on paused listeners
        ArrayList<OnActivityPausedListener> listeners;
        synchronized (mOnPauseListeners) {
            listeners = mOnPauseListeners.remove(r.activity);
        }
        int size = (listeners != null ? listeners.size() : 0);
        for (int i = 0; i < size; i++) {
            listeners.get(i).onPaused(r.activity);
        }


        return state;
    }


        然后调用了:ActivityManagerNative.getDefault().activityPaused

    final void activityPaused(IBinder token, boolean timeout) {
        if (DEBUG_PAUSE) Slog.v(
            TAG, "Activity paused: token=" + token + ", timeout=" + timeout);


        ActivityRecord r = null;


        synchronized (mService) {
            int index = indexOfTokenLocked(token);
            if (index >= 0) {
                r = mHistory.get(index);
                mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
                if (mPausingActivity == r) {
                    if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r
                            + (timeout ? " (due to timeout)" : " (pause complete)"));
                    r.state = ActivityState.PAUSED;
                    completePauseLocked();
                } else {
                    EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
                            r.userId, System.identityHashCode(r), r.shortComponentName, 
                            mPausingActivity != null
                                ? mPausingActivity.shortComponentName : "(none)");
                }
            }
        }
    }

此函数中调用了:completePauseLocked
    private final void completePauseLocked() {
        ActivityRecord prev = mPausingActivity;
        if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev);
        
        if (prev != null) {
            if (prev.finishing) {
                if (DEBUG_PAUSE) Slog.v(TAG, "Executing finish of activity: " + prev);
                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
            } else if (prev.app != null) {
                if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending stop: " + prev);
                if (prev.waitingVisible) {
                    prev.waitingVisible = false;
                    mWaitingVisibleActivities.remove(prev);
                    if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(
                            TAG, "Complete pause, no longer waiting: " + prev);
                }
                if (prev.configDestroy) {
                    // The previous is being paused because the configuration
                    // is changing, which means it is actually stopping...
                    // To juggle the fact that we are also starting a new
                    // instance right now, we need to first completely stop
                    // the current instance before starting the new one.
                    if (DEBUG_PAUSE) Slog.v(TAG, "Destroying after pause: " + prev);
                    destroyActivityLocked(prev, true, false, "pause-config");
                } else {
                    mStoppingActivities.add(prev);
                    if (mStoppingActivities.size() > 3) {
                        // If we already have a few activities waiting to stop,
                        // then give up on things going idle and start clearing
                        // them out.
                        if (DEBUG_PAUSE) Slog.v(TAG, "To many pending stops, forcing idle");
                        scheduleIdleLocked();
                    } else {
                        checkReadyForSleepLocked();
                    }
                }
            } else {
                if (DEBUG_PAUSE) Slog.v(TAG, "App died during pause, not stopping: " + prev);
                prev = null;
            }
            mPausingActivity = null;
        }


        if (!mService.isSleeping()) {
            resumeTopActivityLocked(prev);
        } else {
            checkReadyForSleepLocked();
            ActivityRecord top = topRunningActivityLocked(null);
            if (top == null || (prev != null && top != prev)) {
                // If there are no more activities available to run,
                // do resume anyway to start something.  Also if the top
                // activity on the stack is not the just paused activity,
                // we need to go ahead and resume it to ensure we complete
                // an in-flight app switch.
                resumeTopActivityLocked(null);
            }
        }
        
        if (prev != null) {
            prev.resumeKeyDispatchingLocked();
        }


        if (prev.app != null && prev.cpuTimeAtResume > 0
                && mService.mBatteryStatsService.isOnBattery()) {
            long diff = 0;
            synchronized (mService.mProcessStatsThread) {
                diff = mService.mProcessStats.getCpuTimeForPid(prev.app.pid)
                        - prev.cpuTimeAtResume;
            }
            if (diff > 0) {
                BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics();
                synchronized (bsi) {
                    BatteryStatsImpl.Uid.Proc ps =
                            bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
                            prev.info.packageName);
                    if (ps != null) {
                        ps.addForegroundTimeLocked(diff);
                    }
                }
            }
        }
        prev.cpuTimeAtResume = 0; // reset it
    }

        此函数中调用了: scheduleIdleLocked


    final void scheduleIdleLocked() {
        Message msg = Message.obtain();
        msg.what = IDLE_NOW_MSG;
        mHandler.sendMessage(msg);
    }
        发送了一个IDLE_NOW_MSG广播:

        public void handleMessage(Message msg) {
            switch (msg.what) {
                case IDLE_NOW_MSG: {
                    ActivityRecord r = (ActivityRecord)msg.obj;
                    activityIdleInternal(r != null ? r.appToken : null, false, null);
                } break;

        IDLE_NOW_MSG广播的处理调用了:activityIdleInternal

    final ActivityRecord activityIdleInternal(IBinder token, boolean fromTimeout,
            Configuration config) {
        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);


        ......

        if (booting) {
            mService.finishBooting();
        } else if (startingUsers != null) {
            for (i=0; i<startingUsers.size(); i++) {
                mService.finishUserSwitch(startingUsers.get(i));
            }
        }


        mService.trimApplications();
        //dump();
        //mWindowManager.dump();


        if (enableScreen) {
            mService.enableScreenAfterBoot();
        }


        if (activityRemoved) {
            resumeTopActivityLocked(null);
        }


        return res;
    }


   其调用了mService.finishBooting();
 
    final void finishBooting() {
        IntentFilter pkgFilter = new IntentFilter();
        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
        pkgFilter.addDataScheme("package");
        mContext.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
                if (pkgs != null) {
                    for (String pkg : pkgs) {
                        synchronized (ActivityManagerService.this) {
                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
                                setResultCode(Activity.RESULT_OK);
                                return;
                            }
                        }
                    }
                }
            }
        }, pkgFilter);


        synchronized (this) {
            // Ensure that any processes we had put on hold are now started
            // up.
            final int NP = mProcessesOnHold.size();
            if (NP > 0) {
                ArrayList<ProcessRecord> procs =
                    new ArrayList<ProcessRecord>(mProcessesOnHold);
                for (int ip=0; ip<NP; ip++) {
                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
                            + procs.get(ip));
                    startProcessLocked(procs.get(ip), "on-hold", null);
                }
            }
            
            if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
                // Start looking for apps that are abusing wake locks.
                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
                // Tell anyone interested that we are done booting!
                SystemProperties.set("sys.boot_completed", "1");
                SystemProperties.set("dev.bootcomplete", "1");
                for (int i=0; i<mStartedUsers.size(); i++) {
                    UserStartedState uss = mStartedUsers.valueAt(i);
                    if (uss.mState == UserStartedState.STATE_BOOTING) {
                        uss.mState = UserStartedState.STATE_RUNNING;
                        final int userId = mStartedUsers.keyAt(i);
                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
                        broadcastIntentLocked(null, null, intent,
                                null, null, 0, null, null,
                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
                                false, false, MY_PID, Process.SYSTEM_UID, userId);
                    }
                }
            }
        }
    }




        最终 finishBooting 发送了 Intent.ACTION_BOOT_COMPLETED 广播。



几个问题说明:


1、应用进程与系统进程
       应用进程是指那些运行apk的进程,它们由Zygote派生(fork)而来,上面运行了dalvik虚拟机。
  系统进程:Zygote和system_server进程


2、应用apk与系统apk
       /data/app/下的apk为应用apk
  /system/app/下的apk为系统apk


3、ActivityThread代表应用进程的主线程,而system_server并非一个应用进程,为什么也需要ActivityThread?
       a、因为framework-res.apk除了包含资源文件外,还包含了一些Activity(如关机对话框),这些Activity运行在system_server进程中,所以system_server是一个特殊的应用进程。
  b、通过ActivityThread可以把Android系统提供的组件之间的交互机制和交互接口(如Context提供的API)也拓展到system_server。


4、四大组件:
    activity、service、content provider、broadcast receiver。
    


5、ProcessRecord和IApplicationThread
   AMS与应用进程之间使用binder进行通信。android定义了IApplicationThread接口,此接口定义了AMS和应用进程之间的交互函数。此接口的家族图:
   ActivityThread通过成员变量mAppThread指向它的内部类ApplicationThread。
   
   IApplicationThread的客户端在AMS中,IApplicationThread的Binder服务端在应用进程中。(binder系统支持客户端监听服务端的死亡信息)


        public final void scheduleStopActivity(IBinder token, boolean showWindow,
                int configChanges) {
           queueOrSendMessage(
                showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
                token, 0, configChanges);
        }
    即当AMS想要停止一个Activity时,就会通过IApplicationThread的Binder的客户端函数scheduleStopActivity想ActivityThread所在线程发送一个消息,ActivityThread运行在主线程,所以这个消息最终是由主线程处理的。













































































































































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值