欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    Android应用程序进程启动过程的源代码分析.docx

    • 资源ID:70335309       资源大小:131.20KB        全文页数:26页
    • 资源格式: DOCX        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    Android应用程序进程启动过程的源代码分析.docx

          Android应用程序框架层创建的应用程序进程具有两个特点,一是进程的入口函数是ActivityThread.main,二是进程天然支持Binder进程间通信机制;这两个特点都是在进程的初始化过程中实现的,本文将详细分析Android应用程序进程创建过程中是如何实现这两个特点的。        Android应用程序框架层创建的应用程序进程的入口函数是ActivityThread.main比较好理解,即进程创建完成之后,Android应用程序框架层就会在这个进程中将ActivityThread类加载进来,然后执行它的main函数,这个main函数就是进程执行消息循环的地方了。Android应用程序框架层创建的应用程序进程天然支持Binder进程间通信机制这个特点应该怎么样理解呢?前面我们在学习Android系统的Binder进程间通信机制时说到,它具有四个组件,分别是驱动程序、守护进程、Client以及Server,其中Server组件在初始化时必须进入一个循环中不断地与Binder驱动程序进行到交互,以便获得Client组件发送的请求,具体可参考Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析一文,但是,当我们在Android应用程序中实现Server组件的时候,我们并没有让进程进入一个循环中去等待Client组件的请求,然而,当Client组件得到这个Server组件的远程接口时,却可以顺利地和Server组件进行进程间通信,这就是因为Android应用程序进程在创建的时候就已经启动了一个线程池来支持Server组件和Binder驱动程序之间的交互了,这样,极大地方便了在Android应用程序中创建Server组件。        在Android应用程序框架层中,是由ActivityManagerService组件负责为Android应用程序创建新的进程的,它本来也是运行在一个独立的进程之中,不过这个进程是在系统启动的过程中创建的。ActivityManagerService组件一般会在什么情况下会为应用程序创建一个新的进程呢?当系统决定要在一个新的进程中启动一个Activity或者Service时,它就会创建一个新的进程了,然后在这个新的进程中启动这个Activity或者Service,具体可以参考Android系统在新进程中启动自定义服务过程(startService)的原理分析、Android应用程序启动过程源代码分析和Android应用程序在新的进程中启动新的Activity的方法和过程分析这三篇文章。        ActivityManagerService启动新的进程是从其成员函数startProcessLocked开始的,在深入分析这个过程之前,我们先来看一下进程创建过程的序列图,然后再详细分析每一个步骤。       点击查看大图        Step 1. ActivityManagerService.startProcessLocked        这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:view plain1. public final class ActivityManagerService extends ActivityManagerNative    2.         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback     3.     4.     .    5.     6.     private final void startProcessLocked(ProcessRecord app,    7.                 String hostingType, String hostingNameStr)     8.     9.         .    10.     11.         try     12.             int uid = app.info.uid;    13.             int gids = null;    14.             try     15.                 gids = mContext.getPackageManager().getPackageGids(    16.                     app.info.packageName);    17.              catch (PackageManager.NameNotFoundException e)     18.                 .    19.                 20.                 21.             .    22.     23.             int debugFlags = 0;    24.                 25.             .    26.                 27.             int pid = Process.start("android.app.ActivityThread",    28.                 mSimpleProcessManagement ? app.processName : null, uid, uid,    29.                 gids, debugFlags, null);    30.                 31.             .    32.     33.          catch (RuntimeException e)     34.                 35.             .    36.     37.             38.         39.     40.     .    41.     42.             它调用了Process.start函数开始为应用程序创建新的进程,注意,它传入一个第一个参数为"android.app.ActivityThread",这就是进程初始化时要加载的Java类了,把这个类加载到进程之后,就会把它里面的静态成员函数main作为进程的入口点,后面我们会看到。        Step 2. Process.start         这个函数定义在frameworks/base/core/java/android/os/Process.java文件中:view plain1. public class Process   2.     .  3.   4.     public static final int start(final String processClass,  5.         final String niceName,  6.         int uid, int gid, int gids,  7.         int debugFlags,  8.         String zygoteArgs)  9.       10.         if (supportsProcesses()   11.             try   12.                 return startViaZygote(processClass, niceName, uid, gid, gids,  13.                     debugFlags, zygoteArgs);  14.              catch (ZygoteStartFailedEx ex)   15.                 .  16.               17.          else   18.             .  19.   20.             return 0;  21.           22.       23.   24.     .  25.          这里的supportsProcesses函数返回值为true,它是一个Native函数,实现在frameworks/base/core/jni/android_util_Process.cpp文件中:view plain1. jboolean android_os_Process_supportsProcesses(JNIEnv* env, jobject clazz)  2.   3.     return ProcessState:self()->supportsProcesses();  4.          ProcessState:supportsProcesses函数定义在frameworks/base/libs/binder/ProcessState.cpp文件中:view plain1. bool ProcessState:supportsProcesses() const  2.   3.     return mDriverFD >= 0;  4.          这里的mDriverFD是设备文件/dev/binder的打开描述符,如果成功打开了这个设备文件,那么它的值就会大于等于0,因此,它的返回值为true。       回到Process.start函数中,它调用startViaZygote函数进一步操作。       Step 3. Process.startViaZygote       这个函数定义在frameworks/base/core/java/android/os/Process.java文件中:view plain1. public class Process   2.     .  3.   4.     private static int startViaZygote(final String processClass,  5.             final String niceName,  6.             final int uid, final int gid,  7.             final int gids,  8.             int debugFlags,  9.             String extraArgs)  10.             throws ZygoteStartFailedEx   11.         int pid;  12.   13.         synchronized(Process.class)   14.             ArrayList<String> argsForZygote = new ArrayList<String>();  15.   16.             / -runtime-init, -setuid=, -setgid=,  17.             / and -setgroups= must go first  18.             argsForZygote.add("-runtime-init");  19.             argsForZygote.add("-setuid=" + uid);  20.             argsForZygote.add("-setgid=" + gid);  21.             if (debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0)   22.                 argsForZygote.add("-enable-safemode");  23.               24.             if (debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0)   25.                 argsForZygote.add("-enable-debugger");  26.               27.             if (debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0)   28.                 argsForZygote.add("-enable-checkjni");  29.               30.             if (debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0)   31.                 argsForZygote.add("-enable-assert");  32.               33.   34.             /TODO optionally enable debuger  35.             /argsForZygote.add("-enable-debugger");  36.   37.             / -setgroups is a comma-separated list  38.             if (gids != null && gids.length > 0)   39.                 StringBuilder sb = new StringBuilder();  40.                 sb.append("-setgroups=");  41.   42.                 int sz = gids.length;  43.                 for (int i = 0; i < sz; i+)   44.                     if (i != 0)   45.                         sb.append(',');  46.                       47.                     sb.append(gidsi);  48.                   49.   50.                 argsForZygote.add(sb.toString();  51.               52.   53.             if (niceName != null)   54.                 argsForZygote.add("-nice-name=" + niceName);  55.               56.   57.             argsForZygote.add(processClass);  58.   59.             if (extraArgs != null)   60.                 for (String arg : extraArgs)   61.                     argsForZygote.add(arg);  62.                   63.               64.   65.             pid = zygoteSendArgsAndGetPid(argsForZygote);  66.           67.       68.   69.     .  70.           这个函数将创建进程的参数放到argsForZygote列表中去,如参数"-runtime-init"表示要为新创建的进程初始化运行时库,然后调用zygoteSendAndGetPid函数进一步操作。        Step 4. Process.zygoteSendAndGetPid        这个函数定义在frameworks/base/core/java/android/os/Process.java文件中:view plain1. public class Process   2.     .  3.   4.     private static int zygoteSendArgsAndGetPid(ArrayList<String> args)  5.             throws ZygoteStartFailedEx   6.         int pid;  7.   8.         openZygoteSocketIfNeeded();  9.   10.         try   11.             /* 12.             * See com.android.internal.os.ZygoteInit.readArgumentList() 13.             * Presently the wire format to the zygote process is: 14.             * a) a count of arguments (argc, in essence) 15.             * b) a number of newline-separated argument strings equal to count 16.             * 17.             * After the zygote process reads these it will write the pid of 18.             * the child or -1 on failure. 19.             */  20.   21.             sZygoteWriter.write(Integer.toString(args.size();  22.             sZygoteWriter.newLine();  23.   24.             int sz = args.size();  25.             for (int i = 0; i < sz; i+)   26.                 String arg = args.get(i);  27.                 if (arg.indexOf('n') >= 0)   28.                     throw new ZygoteStartFailedEx(  29.                         "embedded newlines not allowed");  30.                   31.                 sZygoteWriter.write(arg);  32.                 sZygoteWriter.newLine();  33.               34.   35.             sZygoteWriter.flush();  36.   37.             / Should there be a timeout on this?  38.             pid = sZygoteInputStream.readInt();  39.   40.             if (pid < 0)   41.                 throw new ZygoteStartFailedEx("fork() failed");  42.               43.          catch (IOException ex)   44.             .  45.           46.   47.         return pid;  48.       49.   50.     .  51.            这里的sZygoteWriter是一个Socket写入流,是由openZygoteSocketIfNeeded函数打开的:view plain1. public class Process   2.     .  3.   4.     /* 5.     * Tries to open socket to Zygote process if not already open. If 6.     * already open, does nothing.  May block and retry. 7.     */  8.     private static void openZygoteSocketIfNeeded()  9.             throws ZygoteStartFailedEx   10.   11.         int retryCount;  12.   13.         if (sPreviousZygoteOpenFailed)   14.             /* 15.             * If we've failed before, expect that we'll fail again and 16.             * don't pause for retries. 17.             */  18.             retryCount = 0;  19.          else   20.             retryCount = 10;  21.           22.       23.         /* 24.         * See bug #811181: Sometimes runtime can make it up before zygote. 25.         * Really, we'd like to do something better to avoid this condition, 26.         * but for now just wait a bit. 27.         */  28.         for (int retry = 0  29.              (sZygoteSocket = null) && (retry < (retryCount + 1)  30.              retry+ )   31.   32.                 if (retry > 0)   33.                     try   34.                         Log.i("Zygote", "Zygote not up yet, sleeping.");  35.                         Thread.sleep(ZYGOTE_RETRY_MILLIS);  36.                      catch (InterruptedException ex)   37.                         / should never happen  38.                       39.                   40.   41.                 try   42.                     sZygoteSocket = new LocalSocket();  43.                     sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET,  44.                         LocalSocketAddress.Namespace.RESERVED);  45.   46.                     sZygoteInputStream  47.                         = new DataInputStream(sZygoteSocket.getInputStream();  48.   49.                     sZygoteWriter =  50.                         new BufferedWriter(  51.                         new OutputStreamWriter(  52.                         sZygoteSocket.getOutputStream(),  53.                         256);  54.   55.                     Log.i("Zygote", "Process: zygote socket opened");  56.   57.                     sPreviousZygoteOpenFailed = false;  58.                     break;  59.                  catch (IOException ex)   60.                     .  61.                   62.           63.   64.         .  65.       66.   67.     .  68.           这个Socket由frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中的ZygoteInit类在runSelectLoopMode函数侦听的。        Step 5. ZygoteInit.runSelectLoopMode        这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:view plain1. public class ZygoteInit   2.     .  3.   4.     /* 5.     * Runs the zygote process's select loop. Accepts new connections as 6.     * they happen, and reads commands from connections one spawn-request's 7.     * worth at a time. 8.     * 9.     * throws MethodAndArgsCaller in a child process when a main() should 10.     * be executed. 11.     */  12.     private static void runSelectLoopMode() throws MethodAndArgsCaller   13.         ArrayList<FileDescriptor> fds = new ArrayList();  14.         ArrayList<ZygoteConnection> peers = new ArrayList();  15.         FileDescriptor fdArray = new FileDescriptor4;  16.   17.         fds.add(sServerSocket.getFileDescriptor();  18.         peers.add(null);  19.   20.         int loopCount = GC_LOOP_COUNT;  21.         while (true)   22.             int index;  23.             /* 24.             * Call gc() before we block in select(). 25.             * It's work that has to be done anyway, and it's better 26.             * to avoid making every child do it.  It will also 27.             * madvise() any free memory as a side-effect. 28.             * 29.             * Don't call it every time, because walking the entire 30.             * heap is a lot of overhead to free a few hundred bytes. 31.             */  32.             if (loopCount <= 0)   33.                 gc();  34.                 loopCount = GC_LOOP_COUNT;  35.              else   36.                 loopCount-;  37.               38.   39.   40.             try   41.                 fdArray = fds.toArray(fdArray);  42.                 index = selectReadable(fdArray);  43.              catch (IOException ex)   44.                 throw new RuntimeException("Error in select()", ex);  45.               46.   47.             if (index < 0)   48.                 throw new RuntimeException("Error in select()");  49.              else if (index = 0)   50.                 ZygoteConnection newPeer = acceptCommandPeer();  51.                 peers.add(newPeer);  52.                 fds.add(newPeer.getFileDesciptor();  53.              else   54.                 boolean done;  55.                 done = peers.get(index).runOnce();  56.   57.                 if (done)   58.                     peers.remove(index);  59.                     fds.remove(index);  60.                   61.               62.           63.       64.   65.     .  66.           当Step 4将数据通过Socket接口发送出去后,就会下面这个语句:view plain1. done = peers.get(index).runOnce();          这里从peers.get(index)得到的是一个ZygoteConnection对象,表示一个Socket连接,因此,接下来就是调用ZygoteConnection.runOnce函数

    注意事项

    本文(Android应用程序进程启动过程的源代码分析.docx)为本站会员(asd****56)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开