当前位置:操作系统 > 安卓/Android >>

android启动--深入理解启动HOME

ok, 通过前面讲解,系统已经从 init 进程  --> 启动 zygote --> 启动 SystemServer --> ??? 那么现在应该启动什么呢?

 


从前面分析来看,基本的native及 java 世界的环境都已建立完成,那么还差一个HOME主页显示? 可视化系统下面即将开始了。

在讲解 Zygote 中,有一个函数:

main @ frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

 


这里利用  runSelectLoopMode() 函数处理客户连接及客户请求

private static void runSelectLoopMode(){

while (true) {

// 利用select进行多路I/O 监听

index = selectReadable(fdArray);

// 如果有客户端连接则accept并加入到ArrayList中

if (index == 0) {

                ZygoteConnection newPeer = acceptCommandPeer();

                peers.add(newPeer);

                fds.add(newPeer.getFileDesciptor());

       }else {

// 否则交给ZygoteConnection的 runOnce()函数

done = peers.get(index).runOnce();

}

}

...

}

-->

上面在客户端连接使用 ZygoteConnection 类,具体 runOnce()功能如下:

runOnce @ frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java

boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {

args = readArgumentList();

// 根据客户端给定的参数,利用 forkAndSpecialize 创建进程

pid = Zygote.forkAndSpecialize(parsedArgs.uid,

                    parsedArgs.gid,

                    parsedArgs.gids,

                    parsedArgs.debugFlags, rlimits);

 // 根据pid值进行处理子进程及父进程

        if (pid == 0) {

            // in child

            handleChildProc(parsedArgs, descriptors, newStderr);

            // should never happen

            return true;

        } else { /* pid != 0 */

            // in parent...pid of < 0 means failure

            return handleParentProc(pid, descriptors, parsedArgs);

        }

...

}

总结:客户端利用Zygote代表 ZygoteConnection 类请求 zygote 创建新的进程,创建成功后并分别对子进程及父进程单独流程处理。

 


应用安装完毕后,还需要有一个HOME应用来负责将它们在桌面上显示出来,默认就是Launcher2应用程序,这里将介绍一下 Launcher2 启动过程, 主要分为6个大过程来启动:

 


在 SystemServer.java 中对于 ActivityManagerService 的处理简单说明下:

1、ActivityManagerService.main(factoryTest);

通过AThread线程对象来内部创建了一个ActivityManagerService实例,然后将这个实例保存其成员变量mService中,接着又把这个ActivityManagerService实例保存在ActivityManagerService类的静态成员变量mSelf中 :

ActivityManagerService m = new ActivityManagerService();

mService = m;

mSelf = mService;

2、ActivityManagerService.setSystemProcess();

系统中的应用程序的所有信息都保存在PackageManagerService,所需要的应用信息从这里提取即可。

ApplicationInfo info =

               mSelf.mContext.getPackageManager().getApplicationInfo(

                        "android", STOCK_PM_FLAGS);

mSystemThread.installSystemApplicationInfo(info);

3、在run() 函数后半段,有很多的 xxx.systemReady();这里是通知各个服务,系统已经准备就绪。

其中如下代码片段:

// We now tell the activity manager it is okay to run third party

// code.  It will call back into us once it has gotten to the state

// where third party code can really run (but before it has actually

// started launching the initial applications), for us to complete our

// initialization.

((ActivityManagerService)ActivityManagerNative.getDefault())

                .systemReady()

-->

systemReady @ frameworks\base\services\java\com\android\server\am\ActivityManagerSe

rvice.java

public void systemReady(final Runnable goingCallback){

...

resumeTopActivityLocked(null);  // 这里启动Home应用程序

...

}

-->

private final boolean resumeTopActivityLocked(HistoryRecord prev){

// Find the first activity that is not finishing.

HistoryRecord next = topRunningActivityLocked(null);

if (next == null) {

     // There are no more activities!  Let's just start up the

     // Launcher...

     return startHomeActivityLocked();

}

...

}

利用topRunningActivityLocked 返回的是当前系统Activity堆栈最顶端的Activity 而为 null 则调用 topRunningActivityLocked()

4、启动HOME应用程序

private boolean startHomeActivityLocked() {

...

if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {

            intent.addCategory(Intent.CATEGORY_HOME);

}

ActivityInfo aInfo =

             intent.resolveActivityInfo(mContext.getPackageManager(),STOCK_PM_FLAGS);

ProcessRecord app = getProcessRecordLocked(aInfo.processName,aInfo.applicationInfo.uid);

if (app == null || app.instrumentationClass == null) {

startActivityLocked(null, intent, null, null, 0, aInfo,

                        null, null, 0, 0, 0, false, false);

}

}

这里会创建一个 CATEGORY_HOME 类型的 Intent ,通过resolveActivityInfo函数向 PackageManagerService 查询 CATEGORY 是否类型为 HOME 类型应用。这里返回 com.android.launcher2.Launcher 这个 Activity。第一次启动则利用startActivityLocked启动这个Activity。

查看 packages\apps\Launcher2\AndroidManifest.xml 内容:

<intent-filter>

  <action android:name="android.intent.action.MAIN" />

  <category android:name="android.intent.category.HOME" />

  <category android:name="android.intent.category.DEFAULT" />

  <category android:name="android.intent.category.MONKEY"/>

</intent-filter>

5、下面就启动 com.android.launcher2.Launcher 这个 Activity

首先从执行  onCreate 函数开始简单过一下代码调用大致关系:

onCreate --> mModel.startLoader(this, true); -->

调用到 LauncherModel.java

public void startLoader(Context context, boolean isLaunching)

这里并非直接加载应用程序,而是利用发消息由LoaderThread处理

mLoaderThread = new LoaderThread(context, oldThread, isLaunching);

mLoaderThread.start();

-->

public void run() {

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,