zygote 프로세스 시작 프로세스 해독
zygote 프로세스
zygote 서버가 app_에서프로세스가 시작되면 가상 머신이 시작됩니다.가상 머신의 첫 번째 Java 클래스는 ZygoteInit입니다.java.
ZygoteInit의 main 방법
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
// Zygote goes into its own process group.
try {
Os.setpgid(0, 0);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to setpgid(0,0)", ex);
}
final Runnable caller;
try {
...
//1 ServerSocket
zygoteServer.registerServerSocket(socketName);
// In some configurations, we avoid preloading resources and classes eagerly.
// In such cases, we will preload things prior to our first fork.
// 2
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
...
if (startSystemServer) {
//3 SystemServer
Runnable r = forkSystemServer(abiList, socketName, 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.
// zygote , , 。 , return 。
//4
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
//5 socket
zygoteServer.closeServerSocket();
}
// We're in the child process and have exited the select loop. Proceed to execute the
// command.
if (caller != null) {
caller.run();
}
}
1 Zygote Init main 함수의 첫 번째 중요한 작업은 Socket 서버 포트 2를 시작하여 Socket을 만든 후 Framework의 대부분 분류와 자원 3을 미리 설치한 후 System Server 프로세스 앞에 3을 주석한 곳을 만들고 새로운 프로세스를 만드는 것입니다. 이 방법은 두 개의 결과를 되돌려줍니다. 하나는 r가null입니다.현재 프로세스입니다. r는null이 아닙니다.하위 프로세스입니다.r가null일 때 주석 4를 실행합니다.runSelectLoop 메서드에는 클라이언트가 메시지를 보내기를 기다리는 고정 순환이 있습니다.r가null이 아닐 때, 하위 프로세스에 있습니다. 하위 프로세스는 이 포트를 필요로 하지 않기 때문입니다.그래서 닫기
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
...
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
//1 SystemServer
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
//2 SystemServer
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
//3 socket
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
주석 1, 최종적으로nativeForkSystemServer 방법을 호출하여 프로세스 주석 2pid== 0은 생성된 프로세스가 실행하는 코드입니다.handle System Server Process는 최종적으로 Runtime Init에서findStaticMain 방법을 호출합니다.이 측의run방법에서 목표를 실행하는main방법 설명3은 서버 포트를 닫습니다.zygote에서 이전 문장을 복사해서 Socket 서버를 만들었기 때문에, 이 서버는 zygote 자신을 제외하고는 다른 프로세스에 사용되지 말아야 합니다. 그렇지 않으면 시스템에서 여러 프로세스가 Socket 클라이언트의 명령을 받을 수 있습니다.
SystemServer 프로세스
System Server는 zygote가 부화한 첫 번째 프로세스입니다. Zygote Initmain 함수에서 start System Server () 를 호출하는 것을 시작으로 최종적으로native Fork System Server 방법을 호출하여 새 프로세스를 시작한 후 Socket 서버를 닫습니다.SystemServer를 실행하는 main 방법
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
try {
...
// Prepare the main looper thread (this thread).
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
// Looper
Looper.prepareMainLooper();
// Initialize native services.
// so
System.loadLibrary("android_servers");
// Check whether we failed to shut down last time we tried.
// This call may not return.
performPendingShutdown();
// ActivityThread,ContextImpl
// Initialize the system context.
createSystemContext();
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for init tasks that can be parallelized
// ,
SystemServerInitThreadPool.get();
} finally {
traceEnd(); // InitBeforeStartServices
}
// Start services.
try {
traceBeginAndSlog("StartServices");
// , , ,PMS
startBootstrapServices();
// ,
startCoreServices();
//
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
...
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
시작 서비스의 대부분은 System Service Manager의 start Service 방법으로 호출됩니다
public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service);
// Start it.
long time = SystemClock.elapsedRealtime();
try {
// service onStart
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ ": onStart threw an exception", ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}
mian을 직접 실행하는 방법도 있습니다. 예를 들어 다음과 같은 서비스 관리자가 실행됩니다.addService(xxx,m), 서비스를 캐시합니다.
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
public static PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
// Self-check for initial settings.
PackageManagerServiceCompilerMapping.checkProperties();
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore);
m.enableSystemUserPackages();
ServiceManager.addService("package", m);
final PackageManagerNative pmn = m.new PackageManagerNative();
ServiceManager.addService("package_native", pmn);
return m;
}
Service Manager는addService 방법에 추가된 것은name이 IBinder에 대한 참조입니다.이 서비스들은 모두 다른 프로세스에 제공할 수 있기 때문이다.그래서 당연히 아이비입니다.
/**
* Place a new @a service called @a name into the service
* manager.
*
* @param name the name of the new service
* @param service the service object
*/
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
Package Manager Service의 구조 방법을 보면 Service Thread 라인을 초기화합니다.다른 서비스도 라인이 있을 거예요.
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
...
synchronized (mInstallLock) {
// writer
synchronized (mPackages) {
// 。 PackageManagerService
mHandlerThread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
mHandlerThread.start();
mHandler = new PackageHandler(mHandlerThread.getLooper());
}
APK 응용 프로그램에서 직접 상호작용을 할 수 있는 대부분의 시스템 서비스는 시스템 서버 프로세스에서 실행된다. 예를 들어 Windows 관리자 서버, Activity 관리자 시스템 서비스, Package 관리자 서버 등 흔히 볼 수 있는 서비스인데 이런 시스템 서비스는 모두 하나의 라인으로 시스템 서버 프로세스에 존재한다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.