当前位置: 首页 > news >正文

做网站ps的图片百度站长工具使用方法

做网站ps的图片,百度站长工具使用方法,如何做网络推广员,网站设计师要学什么frameworks 之Zygote Zygote.rc 解析Zygote 启动ZygoteInit.javaZygote.cppLiunx fork Zygote 中文意思为受精卵。 和其意思一样,该功能负责android系统孵化service 和 app 进程。 本文讲解Zygote的大概流程。涉及的相同的类,如下所示 system/core/rootd…

frameworks 之Zygote

  • Zygote.rc 解析
  • Zygote 启动
  • ZygoteInit.java
  • Zygote.cpp
  • Liunx fork

Zygote 中文意思为受精卵。 和其意思一样,该功能负责android系统孵化service 和 app 进程。
本文讲解Zygote的大概流程。涉及的相同的类,如下所示

  • system/core/rootdir/init.zygote32.rc
  • frameworks/base/cmds/app_process/app_main.cpp
  • frameworks/base/core/jni/AndroidRuntime.cpp
  • system/core/init/main.cpp
  • frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
  • frameworks/base/core/java/com/android/internal/os/Zygote.java
  • frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

Zygote.rc 解析

启动init进程后,会解析 Zygote.rc文件。该文件位于 system/core/rootdir 文件夹下
其中第一行 zygote 表示进程名, /system/bin/app_process 表示要启动的模块名 ,–zygote --start-system-server 表示参数, class main 表示入口方法。

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
socket usap_pool_primary stream 660 root system
onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
critical window=${zygote.critical_window.minute:-off} target=zygote-fatal

Zygote 启动

根据上面的rc文件 全局搜索 grep app_process ./ -rn
可以看到该模块名为app_process的位于 base/cmds/app_process 下。
在这里插入图片描述
跳转到该文件夹下 打开 app_main.cpp 文件,查看main 方法
main 方法前面是解析参数,并对变量 zygote, startSystemServer 设置为true, 通过 runtime.start 方法启动, start方法是在继承在 AndroidRuntime 类实现

int main(int argc, char* const argv[])
{// Parse runtime arguments.  Stop at first unrecognized option.bool zygote = false;bool startSystemServer = false;bool application = false;String8 niceName;String8 className;// 将变量为true++i;  // Skip unused "parent dir" argument.while (i < argc) {const char* arg = argv[i++];if (strcmp(arg, "--zygote") == 0) {zygote = true;niceName = ZYGOTE_NICE_NAME;} else if (strcmp(arg, "--start-system-server") == 0) {startSystemServer = true;} else if (strcmp(arg, "--application") == 0) {application = true;} else if (strncmp(arg, "--nice-name=", 12) == 0) {niceName.setTo(arg + 12);} else if (strncmp(arg, "--", 2) != 0) {className.setTo(arg);break;} else {--i;break;}}// zygote 为true 通过runtime启动,com.android.internal.os.ZygoteInit 为类名if (zygote) {runtime.start("com.android.internal.os.ZygoteInit", args, zygote);} else if (className) {runtime.start("com.android.internal.os.RuntimeInit", args, zygote);} else {fprintf(stderr, "Error: no class name or --zygote supplied.\n");app_usage();LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");}
}

通过 全局查找 grep “AndroidRuntime” ./ -rn 得到该类的位置 在 core/jni/AndroidRuntime.cpp 下
在这里插入图片描述
该方法前面大部分还是参数变量判断,关键通过 jmethodID startMeth = env->GetStaticMethodID(startClass, “main”,
“([Ljava/lang/String;)V”); 启动 对应的main方法。根据上一步传进来的参数。可以得到启动了 ZygoteInit.java 类

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{/** We want to call main() with a String array with arguments in it.* At present we have two arguments, the class name and an option string.* Create an array to hold them.*/jclass stringClass;jobjectArray strArray;jstring classNameStr;// 省略// 加载传进来的类名,jni 加载对应的main方法char* slashClassName = toSlashClassName(className != NULL ? className : "");jclass startClass = env->FindClass(slashClassName);if (startClass == NULL) {ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);/* keep going */} else {jmethodID startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");if (startMeth == NULL) {ALOGE("JavaVM unable to find main() in '%s'\n", className);/* keep going */} else {env->CallStaticVoidMethod(startClass, startMeth, strArray);#if 0if (env->ExceptionCheck())threadExitUncaughtException(env);
#endif}}free(slashClassName);ALOGD("Shutting down VM\n");if (mJavaVM->DetachCurrentThread() != JNI_OK)ALOGW("Warning: unable to detach main thread\n");if (mJavaVM->DestroyJavaVM() != 0)ALOGW("Warning: VM did not shut down cleanly\n");
}

ZygoteInit.java

查看对应的main方法 ,main 里面主要的方法有如下
preload(bootTimingsTraceLog); 预加载了类,资源,opengl,so库等
初始化ZygoteServer
forkSystemServer 启动 SystemServer
runSelectLoop 循环等待消息

public static void main(String[] argv) {...// 初始化参数 startSystemServer 决定启动 systemServer 服务boolean startSystemServer = false;String zygoteSocketName = "zygote";String abiList = null;boolean enableLazyPreload = false;for (int i = 1; i < argv.length; i++) {if ("start-system-server".equals(argv[i])) {startSystemServer = true;} else if ("--enable-lazy-preload".equals(argv[i])) {enableLazyPreload = true;} else if (argv[i].startsWith(ABI_LIST_ARG)) {abiList = argv[i].substring(ABI_LIST_ARG.length());} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());} else {throw new RuntimeException("Unknown command line argument: " + argv[i]);}}...// In some configurations, we avoid preloading resources and classes eagerly.// In such cases, we will preload things prior to our first fork.if (!enableLazyPreload) {bootTimingsTraceLog.traceBegin("ZygotePreload");EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,SystemClock.uptimeMillis());// 加载类资源 和so preload(bootTimingsTraceLog);EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,SystemClock.uptimeMillis());bootTimingsTraceLog.traceEnd(); // ZygotePreload}...// 创建systemServiver 服务zygoteServer = new ZygoteServer(isPrimaryZygote);if (startSystemServer) {Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);// {@code r == null} in the parent (zygote) process, and {@code r != null} in the// child (system_server) process.if (r != null) {r.run();return;}}...Log.i(TAG, "Accepting command socket connections");// 等待服务// The select loop returns early in the child process after a fork and// loops forever in the zygote.caller = zygoteServer.runSelectLoop(abiList);
}

其中 preload 里面的 preloadClasses 加载android所需的类 ,加载 preloaded-classes 文件 通过Class.forName 加载类。可通过find -name preloaded-classes 查看该文件的位置该文件通过编译时候拷贝到 system/ect目录下 。
在这里插入图片描述

static void preload(TimingsTraceLog bootTimingsTraceLog) {preloadClasses();preloadResources();nativePreloadAppProcessHALs();preloadSharedLibraries();preloadTextResources();
}private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";private static void preloadClasses() {// 加载文件InputStream is;try {is = new FileInputStream(PRELOADED_CLASSES);} catch (FileNotFoundException e) {Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");return;}...// 循环遍历 通过 Class.forName 加载类文件while ((line = br.readLine()) != null) {// Skip comments and blank lines.line = line.trim();if (line.startsWith("#") || line.equals("")) {continue;}Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);try {// Load and explicitly initialize the given class. Use// Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups// (to derive the caller's class-loader). Use true to force initialization, and// null for the boot classpath class-loader (could as well cache the// class-loader of this class in a variable).Class.forName(line, true, null);count++;} catch (ClassNotFoundException e) {if (line.contains("$$Lambda$")) {if (LOGGING_DEBUG) {missingLambdaCount++;}} else {Log.w(TAG, "Class not found for preloading: " + line);}} catch (UnsatisfiedLinkError e) {Log.w(TAG, "Problem preloading " + line + ": " + e);} catch (Throwable t) {Log.e(TAG, "Error preloading " + line + ".", t);if (t instanceof Error) {throw (Error) t;} else if (t instanceof RuntimeException) {throw (RuntimeException) t;} else {throw new RuntimeException(t);}}Trace.traceEnd(Trace.TRACE_TAG_DALVIK);}
}

runSelectLoop 里面是一个死循环,poll等待消息 如果没消息来 就会卡在这 ,如果第一次进来,调用 acceptCommandPeer,接着 acceptCommandPeer 又会调用 createNewConnection方法 创建 ZygoteConnection。

			..// poll等待消息 如果没消息来 就会卡在这try {pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);} catch (ErrnoException ex) {throw new RuntimeException("poll failed", ex);}...//如果第一次进来,调用 acceptCommandPeer,创建 ZygoteConnectionif (pollIndex == 0) {// Zygote server socketZygoteConnection newPeer = acceptCommandPeer(abiList);peers.add(newPeer);socketFDs.add(newPeer.getFileDescriptor());} else if (pollIndex < usapPoolEventFDIndex) {ZygoteConnection connection = peers.get(pollIndex);boolean multipleForksOK = !isUsapPoolEnabled()&& ZygoteHooks.isIndefiniteThreadSuspensionSafe();// 执行创建final Runnable command =connection.processCommand(this, multipleForksOK);}

processCommand 方法里面会调用 forkAndSpecialize 继续调用 nativeForkAndSpecialize 创建进程,而 nativeForkAndSpecialize又会调用 ForkCommon 创建。

if (parsedArgs.mInvokeWith != null || parsedArgs.mStartChildZygote|| !multipleOK || peer.getUid() != Process.SYSTEM_UID) {// Continue using old code for now. TODO: Handle these cases in the other path.// 创建进程pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid,parsedArgs.mGids, parsedArgs.mRuntimeFlags, rlimits,parsedArgs.mMountExternal, parsedArgs.mSeInfo, parsedArgs.mNiceName,fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,parsedArgs.mInstructionSet, parsedArgs.mAppDataDir,parsedArgs.mIsTopApp, parsedArgs.mPkgDataInfoList,parsedArgs.mAllowlistedDataInfoList, parsedArgs.mBindMountAppDataDirs,parsedArgs.mBindMountAppStorageDirs);try {if (pid == 0) {// in childzygoteServer.setForkChild();zygoteServer.closeServerSocket();IoUtils.closeQuietly(serverPipeFd);serverPipeFd = null;return handleChildProc(parsedArgs, childPipeFd,parsedArgs.mStartChildZygote);} else {// In the parent. A pid < 0 indicates a failure and will be handled in// handleParentProc.IoUtils.closeQuietly(childPipeFd);childPipeFd = null;handleParentProc(pid, serverPipeFd);return null;}} finally {IoUtils.closeQuietly(childPipeFd);IoUtils.closeQuietly(serverPipeFd);}}

Zygote.cpp

forkSystemServer 会调用 Zygote.forkSystemServer 方法,而forkSystemServer 又会调用
nativeForkSystemServer 方法, 最终调用到 Zygote.cpp 里面的方法。直接查找 Zygote.cpp 可以看到该文件位于 frameworks/base/core/jni 。

			/* Request to fork the system server process */pid = Zygote.forkSystemServer(parsedArgs.mUid, parsedArgs.mGid,parsedArgs.mGids,parsedArgs.mRuntimeFlags,null,parsedArgs.mPermittedCapabilities,parsedArgs.mEffectiveCapabilities);
	static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {ZygoteHooks.preFork();int pid = nativeForkSystemServer(uid, gid, gids, runtimeFlags, rlimits,permittedCapabilities, effectiveCapabilities);// Set the Java Language thread priority to the default value for new apps.Thread.currentThread().setPriority(Thread.NORM_PRIORITY);ZygoteHooks.postForkCommon();return pid;}

看到关键语句pid 可以看出该方法是fork 出进程id, 调用的是liunx 自带fork方法 孵化出进程,当返回的id为0时候 代表是新进程,可以看到会调用 ForkCommon 方法。

pid_t pid = zygote::ForkCommon(env, true,fds_to_close,fds_to_ignore,true);if (pid == 0) {// System server prcoess does not need data isolation so no need to// know pkg_data_info_list.SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities,effective_capabilities, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,false, nullptr, nullptr, /* is_top_app= */ false,/* pkg_data_info_list */ nullptr,/* allowlisted_data_info_list */ nullptr, false, false);}

查看 ForkCommon 方法。里面调用了 Fork方法 创建进程

// 创建进程
pid_t pid = fork();if (pid == 0) {if (is_priority_fork) {setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);} else {setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN);}// The child process.PreApplicationInit();// Clean up any descriptors which must be closed immediatelyDetachDescriptors(env, fds_to_close, fail_fn);// Invalidate the entries in the USAP table.ClearUsapTable();// Re-open all remaining open file descriptors so that they aren't shared// with the zygote across a fork.gOpenFdTable->ReopenOrDetach(fail_fn);// Turn fdsan back on.android_fdsan_set_error_level(fdsan_error_level);// Reset the fd to the unsolicited zygote socketgSystemServerSocketFd = -1;} else {ALOGD("Forked child process %d", pid);}

Liunx fork

fork函数是 Liunx ,fork() 返回的pid pid等于0 表示三fork新进程执行 不等于0 原来的进程执行代码。新建forkTest.c文件,
touch forkTest.c 内容如下

#include <unistd.h>
#include <stdio.h>int main(void){printf("main current process pid == %d \n", getpid());// 创建进程int pid = fork();// 这里会分开2个线程 pid等于0 表示三fork新进程执行 不等于0 原来的进程执行代码if (pid == 0) {printf("fork newProgress child process pid = %d parent pid = %d \n", getpid(), getppid());} else {printf("this process pid = %d forkPid = %d parent pid = %d \n", getpid(),pid, getppid());}return 0;
}

然后执行 gcc forkTest.c -o forkTest 编译为二进制文件 ,在执行 ./forkTest 命令执行 查看打印

main current process pid == 7766 
this process pid = 7766 forkPid = 7767 parent pid = 7144 
fork newProgress child process pid = 7767 parent pid = 7766 
http://www.ds6.com.cn/news/13955.html

相关文章:

  • 做电影网站不放国内主机bt磁力搜索引擎
  • 网站更改建设方案模板高端大气网站建设
  • 做网站文字字号大小太原全网推广
  • 上海 网站建设 外包免费推广方式都有哪些
  • 菠菜网站建设条件免费网站推广平台
  • 网站建设与维护技术浅谈论文怎么申请自己的网络平台
  • 网站建设1000zhu商丘seo外包
  • 建网站公司是如何赚钱论坛推广
  • 注册进出口贸易公司条件广州网页seo排名
  • 58同城网站建设 推广软文推广新闻发布
  • b2b网站名和网址软文代写是什么
  • 南京 网站备案百度优化师
  • 做消防哪些网站找工作软文写作是什么意思
  • 韩国网站购物佛山网络公司 乐云seo
  • 政府网站信息建设工作seo排名优化服务
  • 无锡专业网站建设必应搜索引擎网站
  • 个人网站怎么建立步骤珠海网站seo
  • 网站模板小偷江西seo推广
  • 百度网站建设微信封面推广代理登录页面
  • 微信网站建站平台腾讯广告联盟官网
  • 济宁建设工程信息网在广州做seo找哪家公司
  • o2o与网站建设论文网站软文推广范文
  • 苏州外贸公司网站建设流程图千峰培训出来好就业吗
  • 个人或主题网站建设实验报告seo范畴有哪些
  • 毕设做网站太简单劳动局免费培训项目
  • 网站建设moban网红营销
  • 郑州平台网站建设平台营销
  • 庄河城乡建设管理局网站香水推广软文
  • 企业网站建设的层次广州seo关键词
  • 域名解析到网站谷歌seo建站