Chinaunix首页 | 论坛 | 博客
  • 博客访问: 258838
  • 博文数量: 49
  • 博客积分: 1231
  • 博客等级: 少尉
  • 技术积分: 967
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-02 00:04
个人简介

-->软硬件结合的系统级开发工程师,带过团队,爱好心理学,哲学,艺术...偶像:达芬奇

文章存档

2014年(2)

2013年(4)

2012年(15)

2011年(28)

分类: 嵌入式

2012-09-17 18:58:32

Android系统(Ver2.2)初始启动到SurfaceFlinger启动过程详细分析!
 
 
 SurfaceFlinger启动先从Zygote分析开始,Zygote进程服务创建以前是Linux系统初始化过程,Zygote进程服务创建以后是Android系统开始初始化过程。
 
一。Zygote进程服务的产生
 
1.  init进程服务的产生

  Zygote进程服务的产生还是从init进程开始。
  Android系统在启动时首先会启动Linux系统,引导加载Linux Kernel并启动init进程。Init进程是一个由内核启动的用户级进程,是Android系统的第一个进程。该进程的相关代码在./android-2.2/system/core/init/init.c。在main函数中,有如下代码:

点击(此处)折叠或打开

  1. /* We must have some place other than / to create the
  2.          * device nodes for kmsg and null, otherwise we won't
  3.          * be able to remount / read-only later on.
  4.          * Now that tmpfs is mounted on /dev, we can actually
  5.          * talk to the outside world.
  6.          */
  7.     open_devnull_stdio();
  8.     log_init();
  9.     
  10.     INFO("reading config file\n");
  11.     init_parse_config_file("/init.rc");

  12.     /* pull the kernel commandline and ramdisk properties file in */
  13.     import_kernel_cmdline(0);

  14.     get_hardware_name(hardware, &revision);
  15.     snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
  16.     init_parse_config_file(tmp);
  这里会加载解析init.rc和init.hardware.rc两个初始化脚本。*.rc文件定义了在init进程中需要启动哪些进程服务和执行哪些动作。其详细说明参见./android-2.2/system/core/init/readme.txt。
 
  其中init_parse_config_file("init.rc")函数调入了init.rc配置文件:

点击(此处)折叠或打开

  1. service servicemanager /system/bin/servicemanager
  2.     user system
  3.     critical
  4.     onrestart restart zygote
  5.     onrestart restart media

  6. service vold /system/bin/vold
  7.     socket vold stream 0660 root mount
  8.     ioprio be 2

  9. service netd /system/bin/netd
  10.     socket netd stream 0660 root system
  11.     socket dnsproxyd stream 0660 root inet

  12. service debuggerd /system/bin/debuggerd

  13. service ril-daemon /system/bin/rild
  14.     socket rild stream 660 root radio
  15.     socket rild-debug stream 660 radio system
  16.     user root
  17.     group radio cache inet misc audio sdcard_rw

  18. service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
  19.     socket zygote stream 666
  20.     onrestart write /sys/android_power/request_state wake
  21.     onrestart write /sys/power/state on
  22.     onrestart restart media
  23.     onrestart restart netd

  24. service drm /system/bin/drmserver
  25.     user drm
  26.     group system root inet
  其中实现解析init.rc配置文件的过程详细见./android-2.2/system/core/init/parser.c文件,解析所得服务添加到service_list中,动作添加到action_list中。
  在./android-2.2/system/core/init/init.c初始化文件中的main函数中,最后的一段初始化阶段代码进入主进程循环:

点击(此处)折叠或打开

  1. for(;;) {
  2.         int nr, i, timeout = -1;

  3.         execute_one_command();
  4.         restart_processes();
  5.        
  6.       .
  7.       .
  8.       .
  9. }
  其中, execute_one_command()函数执行所有在queue_list列表里的action,restart_processes()函数运行重起service_list里的服务所有进程。其中包括ServiceManager进程、Zygote进程。
 
2.  ServiceManager进程服务的产生

  ServiceManager进程是所有服务的管理器。
  在./android-2.2/system/core/rootdir/init.rc中对ServiceManager的描述为:

点击(此处)折叠或打开

  1. service servicemanager /system/bin/servicemanager
  2.     user system
  3.     critical
  4.     onrestart restart zygote
  5.     onrestart restart media
  其中,servicemanager服务进程由init启动,“user system”字段表明启动用户为系统用户;“critical”字段表明这是一个设备关键服务 (device-critical service) . 如果它在 4 分钟内退出超过 4 次, 设备将重启并进入恢复模式;“onrestart”字段表明当服务重启时执行一个命令,包括zygote的命令和media的命令。
  而解析这段servicemanager配置文件的程序为./android-2.2/frameworks/base/cmds/servicemanager/service_manager.c源码,它实现了servicemanager服务进程的启动,其中main函数有如下代码:

点击(此处)折叠或打开

  1. int main(int argc, char **argv)
  2. {
  3.     struct binder_state *bs;
  4.     void *svcmgr = BINDER_SERVICE_MANAGER;

  5.     bs = binder_open(128*1024);

  6.     if (binder_become_context_manager(bs)) {
  7.         LOGE("cannot become context manager (%s)\n", strerror(errno));
  8.         return -1;
  9.     }

  10.     svcmgr_handle = svcmgr;
  11.     binder_loop(bs, svcmgr_handler);
  12.     return 0;
  13. }
  首先,调用binder_open()打开Binder设备(/dev/binder),调用binder_become_context_manager()把当前进程设置为ServiceManager。ServiceManager本身就是一个服务。
  其中,binder_become_context_manager()函数在./android-2.2/frameworks/base/cmds/servicemanager/binder.c中实现:

点击(此处)折叠或打开

  1. int binder_become_context_manager(struct binder_state *bs)
  2. {
  3.     return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
  4. }
  最后binder_loop()进入循环状态,并设置svcmgr_handler回调函数等待添加、查询、获取服务等请求。
 
3.  Zygote进程服务的产生

  Zygote进程用于产生Android系统其他进程。
  在./android-2.2/system/core/rootdir/init.rc中对Zygote的描述为:

点击(此处)折叠或打开

  1. service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
  2.     socket zygote stream 666
  3.     onrestart write /sys/android_power/request_state wake
  4.     onrestart write /sys/power/state on
  5.     onrestart restart media
  6.     onrestart restart netd
  其中,“socket zygote stream 666”字段表明创建一个名为 /dev/socket/zygote 的 unix domin socket ,并传送它的 fd 到已启动的进程,为stream流类型",用户和组默认为 0;“onrestart write /sys/android_power/request_state wake”字段表明Android系统电源状态唤醒被写入/sys/android_power/request_state文件;“onrestart write /sys/power/state on”字段表明系统电源状态被开启。
  而解析这段zygote配置文件的程序为./android-2.2/frameworks/base/cmds/app_process/app_main.cpp源码,它实现了zygote服务进程的启动,其中main函数有如下代码:

点击(此处)折叠或打开

  1. int main(int argc, const char* const argv[])
  2. {
  3.     // These are global variables in ProcessState.cpp
  4.     mArgC = argc;
  5.     mArgV = argv;
  6.     
  7.     mArgLen = 0;
  8.     for (int i=0; i<argc; i++) {
  9.         mArgLen += strlen(argv[i]) + 1;
  10.     }
  11.     mArgLen--;

  12.     AppRuntime runtime;
  13.     const char *arg;
  14.     const char *argv0;

  15.     argv0 = argv[0];

  16.     // Process command line arguments
  17.     // ignore argv[0]
  18.     argc--;
  19.     argv++;

  20.     // Everything up to '--' or first non '-' arg goes to the vm
  21.     
  22.     int i = runtime.addVmArguments(argc, argv);

  23.     // Next arg is parent directory
  24.     if (i < argc) {
  25.         runtime.mParentDir = argv[i++];
  26.     }

  27.     // Next arg is startup classname or "--zygote"
  28.     if (i < argc) {
  29.         arg = argv[i++];
  30.         if (0 == strcmp("--zygote", arg)) {
  31.             bool startSystemServer = (i < argc) ?
  32.                     strcmp(argv[i], "--start-system-server") == 0 : false;
  33.             setArgv0(argv0, "zygote");
  34.             set_process_name("zygote");
  35.             runtime.start("com.android.internal.os.ZygoteInit",
  36.                 startSystemServer);
  37.         } else {
  38.             set_process_name(argv0);

  39.             runtime.mClassName = arg;

  40.             // Remainder of args get passed to startup class main()
  41.             runtime.mArgC = argc-i;
  42.             runtime.mArgV = argv+i;

  43.             LOGV("App process is starting with pid=%d, class=%s.\n",
  44.                  getpid(), runtime.getClassName());
  45.             runtime.start();
  46.         }
  47.     } else {
  48.         LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
  49.         fprintf(stderr, "Error: no class name or --zygote supplied.\n");
  50.         app_usage();
  51.         return 10;
  52.     }

  53. }
  首先,创建AppRuntime的一个对象runtime,既AppRuntim类继承于AndroidRuntime,既建立了一个Dalvik虚拟机。从runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);语句,通过runtime对象传递com.android.internal.os.ZygoteInit参数,从而由Dalvik虚拟机运行./android-2.2/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中的main函数,开始创建Zygote进程。在其main()中,如下所示:

点击(此处)折叠或打开

  1. public static void main(String argv[]) {
  2.         try {
  3.             VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024);

  4.             // Start profiling the zygote initialization.

  5.             SamplingProfilerIntegration.start();

  6.             registerZygoteSocket();
  7.             EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
  8.                 SystemClock.uptimeMillis());
  9.             preloadClasses();
  10.             //cacheRegisterMaps();

  11.             preloadResources();
  12.             EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
  13.                 SystemClock.uptimeMillis());

  14.             // Finish profiling the zygote initialization.

  15.             SamplingProfilerIntegration.writeZygoteSnapshot();

  16.             // Do an initial gc to clean up after startup

  17.             gc();

  18.             // If requested, start system server directly from Zygote

  19.             if (argv.length != 2) {
  20.                 throw new RuntimeException(argv[0] + USAGE_STRING);
  21.             }

  22.             if (argv[1].equals("true")) {
  23.                 startSystemServer();
  24.             } else if (!argv[1].equals("false")) {
  25.                 throw new RuntimeException(argv[0] + USAGE_STRING);
  26.             }

  27.             Log.i(TAG, "Accepting command socket connections");

  28.             if (ZYGOTE_FORK_MODE) {
  29.                 runForkMode();
  30.             } else {
  31.                 runSelectLoopMode();
  32.             }

  33.             closeServerSocket();
  34.         } catch (MethodAndArgsCaller caller) {
  35.             caller.run();
  36.         } catch (RuntimeException ex) {
  37.             Log.e(TAG, "Zygote died with exception", ex);
  38.             closeServerSocket();
  39.             throw ex;
  40.         }
  41.     }
  首先通过registerZygoteSocket()登记端口,接着preloadClasses()装载相关类。这里大概要装载1000多个类,具体装载类见./android-2.2/frameworks/base/preloaded-classes文件。此文件由./android-2.2/frameworks/base/tools/preload/WritePreloadedClassFile.java产生。分析下该类的main函数:

点击(此处)折叠或打开

  1. public static void main(String[] args) throws IOException,
  2.             ClassNotFoundException {
  3.         if (args.length != 1) {
  4.             System.err.println("Usage: WritePreloadedClassFile [compiled log]");
  5.             System.exit(-1);
  6.         }
  7.         String rootFile = args[0];
  8.         Root root = Root.fromFile(rootFile);

  9.         // No classes are preloaded to start.

  10.         for (LoadedClass loadedClass : root.loadedClasses.values()) {
  11.             loadedClass.preloaded = false;
  12.         }

  13.         // Open preloaded-classes file for output.

  14.         Writer out = new BufferedWriter(new OutputStreamWriter(
  15.                 new FileOutputStream(Policy.PRELOADED_CLASS_FILE),
  16.                 Charset.forName("US-ASCII")));

  17.         out.write("# Classes which are preloaded by"
  18.                 + " com.android.internal.os.ZygoteInit.\n");
  19.         out.write("# Automatically generated by frameworks/base/tools/preload/"
  20.             + WritePreloadedClassFile.class.getSimpleName() + ".java.\n");
  21.         out.write("# MIN_LOAD_TIME_MICROS=" + MIN_LOAD_TIME_MICROS + "\n");
  22.         out.write("# MIN_PROCESSES=" + MIN_PROCESSES + "\n");

  23.         /*
  24.          * The set of classes to preload. We preload a class if:
  25.          *
  26.          * a) it's loaded in the bootclasspath (i.e., is a system class)
  27.          * b) it takes > MIN_LOAD_TIME_MICROS us to load, and
  28.          * c) it's loaded by more than one process, or it's loaded by an
  29.          * application (i.e., not a long running service)
  30.          */
  31.         Set<LoadedClass> toPreload = new TreeSet<LoadedClass>();

  32.         // Preload classes that were loaded by at least 2 processes. Hopefully,

  33.         // the memory associated with these classes will be shared.

  34.         for (LoadedClass loadedClass : root.loadedClasses.values()) {
  35.             Set<String> names = loadedClass.processNames();
  36.             if (!Policy.isPreloadable(loadedClass)) {
  37.                 continue;
  38.             }

  39.             if (names.size() >= MIN_PROCESSES ||
  40.                     (loadedClass.medianTimeMicros() > MIN_LOAD_TIME_MICROS && names.size() > 1)) {
  41.                 toPreload.add(loadedClass);
  42.             }
  43.         }

  44.         int initialSize = toPreload.size();
  45.         System.out.println(initialSize
  46.                 + " classses were loaded by more than one app.");

  47.         // Preload eligable classes from applications (not long-running

  48.         // services).

  49.         for (Proc proc : root.processes.values()) {
  50.             if (proc.fromZygote() && !Policy.isService(proc.name)) {
  51.                 for (Operation operation : proc.operations) {
  52.                     LoadedClass loadedClass = operation.loadedClass;
  53.                     if (shouldPreload(loadedClass)) {
  54.                         toPreload.add(loadedClass);
  55.                     }
  56.                 }
  57.             }
  58.         }

  59.         System.out.println("Added " + (toPreload.size() - initialSize)
  60.                 + " more to speed up applications.");

  61.         System.out.println(toPreload.size()
  62.                 + " total classes will be preloaded.");

  63.         // Make classes that were implicitly loaded by the zygote explicit.

  64.         // This adds minimal overhead but avoid confusion about classes not

  65.         // appearing in the list.

  66.         addAllClassesFrom("zygote", root, toPreload);

  67.         for (LoadedClass loadedClass : toPreload) {
  68.             out.write(loadedClass.name + "\n");
  69.         }

  70.         out.close();

  71.         // Update data to reflect LoadedClass.preloaded changes.

  72.         for (LoadedClass loadedClass : toPreload) {
  73.             loadedClass.preloaded = true;
  74.         }
  75.         root.toFile(rootFile);
  76.     }
  其中MIN_LOAD_TIME_MICROS等于1250,当类的装载时间大于1.25ms,则需要预装载。而Policy.isPreloadable()定义在./android-2.2/frameworks/base/tools/preload/Policy.java文件中如下:

点击(此处)折叠或打开

  1. /**Reports if the given class should be preloaded. */
  2.     public static boolean isPreloadable(LoadedClass clazz) {
  3.         return clazz.systemClass && !EXCLUDED_CLASSES.contains(clazz.name);
  4.     }
  其中EXCLUDED_CLASSES在./android-2.2/frameworks/base/tools/preload/Policy.java文件中如下定义:

点击(此处)折叠或打开

  1. /**
  2.      * Classes which we shouldn't load from the Zygote.
  3.      */
  4.     private static final Set<String> EXCLUDED_CLASSES
  5.             = new HashSet<String>(Arrays.asList(
  6.         // Binders

  7.         "android.app.AlarmManager",
  8.         "android.app.SearchManager",
  9.         "android.os.FileObserver",
  10.         "com.android.server.PackageManagerService$AppDirObserver",

  11.         // Threads

  12.         "android.os.AsyncTask",
  13.         "android.pim.ContactsAsyncHelper",
  14.         "java.lang.ProcessManager"
  15.     ));
  这几个Binders和Thread是不会被预加载的。

  另外,在./android-2.2/frameworks/base/tools/preload/WritePreloadedClassFile.java文件中还有一些application需要装载,要求满足条件proc.fromZygote()且不是属于常驻内存的服务Policy.isService(proc.name)。isService(String processName)定义在./android-2.2/frameworks/base/tools/preload/Policy.java文件中如下:

点击(此处)折叠或打开

  1. /**
  2.      * Returns true if the given process name is a "long running" process or
  3.      * service.
  4.      */
  5.     public static boolean isService(String processName) {
  6.         return SERVICES.contains(processName);
  7.     }
  其中的SERVICES在./android-2.2/frameworks/base/tools/preload/Policy.java文件中如下定义:

点击(此处)折叠或打开

  1. /**
  2.      * Long running services. These are restricted in their contribution to the
  3.      * preloader because their launch time is less critical.
  4.      */
  5.     // TODO: Generate this automatically from package manager.

  6.     private static final Set<String> SERVICES = new HashSet<String>(Arrays.asList(
  7.         "system_server",
  8.         "com.google.process.content",
  9.         "android.process.media",
  10.         "com.android.bluetooth",
  11.         "com.android.calendar",
  12.         "com.android.inputmethod.latin",
  13.         "com.android.phone",
  14.         "com.google.android.apps.maps.FriendService", // pre froyo

  15.         "com.google.android.apps.maps:FriendService", // froyo

  16.         "com.google.android.apps.maps.LocationFriendService",
  17.         "com.google.android.deskclock",
  18.         "com.google.process.gapps",
  19.         "android.tts"
  20.     ));
  preloaded-classes是在下载源码的时候生成,WritePreloadedClassFile类并没有被用到,但可以通过这个类了解Android系统对预加载类的默认要求,参考修改preloaded-classes文件,减少开机初始化时要预加载的类,提高开机速度。
 
  在./android-2.2/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中的main函数中:

点击(此处)折叠或打开

  1. if (argv[1].equals("true")) {
  2.                 startSystemServer();
  3.             } else if (!argv[1].equals("false")) {
  4.                 throw new RuntimeException(argv[0] + USAGE_STRING);
  5.             }
  最后来通过startSystemServer()启动SystemServer进程。其定义在./android-2.2/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

点击(此处)折叠或打开

  1. /**
  2.      * Prepare the arguments and fork for the system server process.
  3.      */
  4.     private static boolean startSystemServer()
  5.             throws MethodAndArgsCaller, RuntimeException {
  6.         /* Hardcoded command line to start the system server */
  7.         String args[] = {
  8.             "--setuid=1000",
  9.             "--setgid=1000",
  10.             "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",
  11.             "--capabilities=130104352,130104352",
  12.             "--runtime-init",
  13.             "--nice-name=system_server",
  14.             "com.android.server.SystemServer",
  15.         };
  16.         ZygoteConnection.Arguments parsedArgs = null;

  17.         int pid;

  18.         try {
  19.             parsedArgs = new ZygoteConnection.Arguments(args);

  20.             /*
  21.              * Enable debugging of the system process if *either* the command line flags
  22.              * indicate it should be debuggable or the ro.debuggable system property
  23.              * is set to "1"
  24.              */
  25.             int debugFlags = parsedArgs.debugFlags;
  26.             if ("1".equals(SystemProperties.get("ro.debuggable")))
  27.                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;

  28.             /* Request to fork the system server process */
  29.             pid = Zygote.forkSystemServer(
  30.                     parsedArgs.uid, parsedArgs.gid,
  31.                     parsedArgs.gids, debugFlags, null,
  32.                     parsedArgs.permittedCapabilities,
  33.                     parsedArgs.effectiveCapabilities);
  34.         } catch (IllegalArgumentException ex) {
  35.             throw new RuntimeException(ex);
  36.         }

  37.         /* For child process */
  38.         if (pid == 0) {
  39.             handleSystemServerProcess(parsedArgs);
  40.         }

  41.         return true;
  42.     }
 
  Zygote包装了Linux的fork。Zygote.forkSystemServer()调用forkAndSpecialize(),文件./android-2.2/dalvik/libcore/dalvik/src/main/java/dalvik/system/Zygote.java定义了forkAndSpecialize()函数:

点击(此处)折叠或打开

  1. /**
  2.      * Forks a new VM instance.
  3.      * @deprecated use {@link Zygote#forkAndSpecialize(int, int, int[], int, int[][])}
  4.      */
  5.     @Deprecated
  6.     public static int forkAndSpecialize(int uid, int gid, int[] gids,
  7.             boolean enableDebugger, int[][] rlimits) {
  8.         int debugFlags = enableDebugger ? DEBUG_ENABLE_DEBUGGER : 0;
  9.         return forkAndSpecialize(uid, gid, gids, debugFlags, rlimits);
  10.     }
  最终穿过虚拟机调用./android-2.2/dalvik/vm/native/dalvik_system_Zygote.c文件中的Dalvik_dalvik_system_Zygote_forkAndSpecialize()函数,由dalvik完成fork新的进程。
  在./android-2.2/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中的main函数中最后会调用runSelectLoopMode(),进入while循环,由peers创建新的进程。
 
 
二。SystemService进程服务的产生

  从上面的分析可以知道,SystemService服务进程是由Zygote服务进程fork出来的一个服务子进程。SystemService用于创建init.rc定义的服务之外的所有服务。
  在文件./android-2.2/frameworks/base/services/java/com/android/server/SystemServer.java中,main()函数中有如下代码:

点击(此处)折叠或打开

  1. // The system server has to run all of the time, so it needs to be

  2.         // as efficient as possible with its memory usage.

  3.         VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
  4.         
  5.         System.loadLibrary("android_servers");
  6.         init1(args);
  Init1()是在native空间实现的,用于启动native空间的服务,其实现是在./android-2.2/frameworks/base/services/jni/com_android_server_SystemServer.cpp文件中的android_server_SystemServer_init1()函数:

点击(此处)折叠或打开

  1. static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
  2. {
  3.     system_init();
  4. }
  而system_init()函数服务初始化创建native层的各个服务,包括SurfaceFlinger服务的启动。system_init()函数被定义在./android-2.2/frameworks/base/cmds/system_server/library/system_init.cpp文件中:

点击(此处)折叠或打开

  1. extern "C" status_t system_init()
  2. {
  3.     LOGI("Entered system_init()");
  4.     
  5.     sp<ProcessState> proc(ProcessState::self());
  6.     
  7.     sp<IServiceManager> sm = defaultServiceManager();
  8.     LOGI("ServiceManager: %p\n", sm.get());
  9.     
  10.     sp<GrimReaper> grim = new GrimReaper();
  11.     sm->asBinder()->linkToDeath(grim, grim.get(), 0);
  12.     
  13.     char propBuf[PROPERTY_VALUE_MAX];
  14.     property_get("system_init.startsurfaceflinger", propBuf, "1");
  15.     if (strcmp(propBuf, "1") == 0) {
  16.         // Start the SurfaceFlinger
  17.         SurfaceFlinger::instantiate();
  18.     }
  在这里如果system_init.startsurfaceflinger字段值为1,就启动SurfaceFlinger线程类服务,其中SurfaceFlinger::instantiate();函数的定义在./android-2.2/frameworks/base/libs/surfaceflinger/SurfaceFlinger.cpp文件中定义:

点击(此处)折叠或打开

  1. void SurfaceFlinger::instantiate() {
  2.     defaultServiceManager()->addService(
  3.             String16("SurfaceFlinger"), new SurfaceFlinger());
  4. }
  通过addService()函数来注册SurfaceFlinger服务,这样就初始化了SurfaceFlinger服务环境,建造了对象,运行了构造函数。

















 



阅读(2146) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~