Android Framework實戰視訊--FallbackHome程序啟動及Activity啟動篇
線上學習課程,課程諮詢答疑和新課資訊:QQ交流群:422901085進行課程討論
轉自於:https://blog.csdn.net/learnframework/article/details/116404083
Android Framework實戰視訊--FallbackHome程序啟動及Activity啟動篇
課程答疑和新課資訊:QQ交流群:422901085進行課程討論
FrameWork入門課視訊連結:https://edu.csdn.net/course/detail/30298
FrameWork實戰課1視訊連結:https://edu.csdn.net/course/detail/30275
專題部落格系列:
Android 8.1 zygote 啟動過程原始碼
Android Framework實戰視訊--Zygote的fork程序篇
Android Framework實戰視訊--SystemServer啟動篇
Android Framework實戰視訊--SystemServer啟動FallbackHome篇
Android Framework實戰視訊--FallbackHome程序啟動及Activity啟動篇
Android Framework實戰視訊--FallbackHome結束啟動Launcher篇
android 8.1 原始碼中FallbackHome程序啟動及Activity啟動分析
上一節課已經一步步分析到了Process.start了,那本節就是來分析Process的start方法具體是怎麼一步步的把程序啟動及程序啟動後對應的Activity是怎麼啟動的
1 應用程序的建立
首先看Process.start的原始碼:
public static final ProcessStartResult start(final String processClass, final String niceName, int uid, int gid, int[] gids, int debugFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String invokeWith, String[] zygoteArgs) { return zygoteProcess.start(processClass, niceName, uid, gid, gids, debugFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, zygoteArgs); }
這裡呼叫了ZygoteProcess的start方法:
public final Process.ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
throw new RuntimeException(
"Starting VM process through Zygote failed", ex);
}
}
這裡呼叫到了startViaZygote方法:
private Process.ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] extraArgs)
throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<String>();
// --runtime-args, --setuid=, --setgid=,
// and --setgroups= must go first
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
//省略
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
這裡設定了一系列引數後,在呼叫zygoteSendArgsAndGetResult
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
//省略
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
writer.write(Integer.toString(args.size()));
writer.newLine();
for (int i = 0; i < sz; i++) {
String arg = args.get(i);
writer.write(arg);
writer.newLine();
}
writer.flush();
// Should there be a timeout on this?
Process.ProcessStartResult result = new Process.ProcessStartResult();
// Always read the entire result from the input stream to avoid leaving
// bytes in the stream for future process starts to accidentally stumble
// upon.
result.pid = inputStream.readInt();
result.usingWrapper = inputStream.readBoolean();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
} catch (IOException ex) {
zygoteState.close();
throw new ZygoteStartFailedEx(ex);
}
}
zygoteSendArgsAndGetResult這裡就呼叫了BufferedWriter的writer物件進行了socket的寫入資料,writer就是zygoteState.writer,
那zygoteState.writer又具體是怎麼賦值的呢?
public static ZygoteState connect(String socketAddress) throws IOException {
DataInputStream zygoteInputStream = null;
BufferedWriter zygoteWriter = null;
final LocalSocket zygoteSocket = new LocalSocket();
try {
//連線zygote程序的serversocket
zygoteSocket.connect(new LocalSocketAddress(socketAddress,
LocalSocketAddress.Namespace.RESERVED));
//socket中的輸入流
zygoteInputStream = new DataInputStream(zygoteSocket.getInputStream());
//socket中的輸出流
zygoteWriter = new BufferedWriter(new OutputStreamWriter(
zygoteSocket.getOutputStream()), 256);
} catch (IOException ex) {
try {
zygoteSocket.close();
} catch (IOException ignore) {
}
throw ex;
}
String abiListString = getAbiList(zygoteWriter, zygoteInputStream);
Log.i("Zygote", "Process: zygote socket " + socketAddress + " opened, supported ABIS: "
+ abiListString);
return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter,
Arrays.asList(abiListString.split(",")));
}
這裡面的socketAddress是如下程式碼賦值的:
public static final ZygoteProcess zygoteProcess =
new ZygoteProcess(ZYGOTE_SOCKET, SECONDARY_ZYGOTE_SOCKET);
public static final String ZYGOTE_SOCKET = "zygote";
也就是ZYGOTE_SOCKET變數,變數就是前幾節課講的zygote程序建立的Server名字
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java中的main方法中:
String socketName = "zygote";
所以就是這樣ActivtiyManagerService通過socket與zygote進行一個跨程序通訊。
ActivityManagerService這邊把要建立一個程序的主要引數等需要準備好,然後傳送給zygote端,zygote端接受到了發來資料後建立對應的程序。建立對應程序時候還會執行傳過來的entryPoint即 "android.app.ActivityThread"類的main方法
接下來看看分析之前Zygote部分的接受和建立程序,前面zygote已經知道,zygote本身是一直迴圈執行runSelectLoop裡面的While:
Runnable runSelectLoop(String abiList) {
//省略;
while (true) {
//省略;
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
//如果是本身serverSocket的fd有輸入訊息,則儲存住新建連線的客戶端peer和fd,比如:第一次AMS就需要繫結
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
try {
//如果哪個peer或者fd有訊息了,則processOneCommand讀取裡面訊息
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);
if (mIsForkChild) {
//省略
return command;
}
}
}
所以核心在processOneCommand方法:
Runnable processOneCommand(ZygoteServer zygoteServer) {
String args[];
Arguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
//讀取傳送過來的引數
args = readArgumentList();
descriptors = mSocket.getAncillaryFileDescriptors();
}
//省略
parsedArgs = new Arguments(args);
//省略
//根據引數建立對應的程序,這裡本質和以前分析system server程序建立一樣
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
parsedArgs.appDataDir);
try {
if (pid == 0) {
//省略
return handleChildProc(parsedArgs, descriptors, childPipeFd);
}
//省略
}
這裡processOneCommand建立好了程序後,又呼叫handleChildProc方法:
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd) {
//省略
//這裡最後呼叫ZygoteInit.zygoteInit和以前systemserver其實是一樣的,只不過這裡的remainingArgs引數變成ActivityThread
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
null /* classLoader */);
}
/這裡最後呼叫ZygoteInit.zygoteInit和以前systemserver其實是一樣的,只不過這裡的remainingArgs引數變成ActivityThread類,返回的ActivityThread的main方法執行的Runable
2 應用程序的Activity啟動
當應用程序被建立後,最開始就是執行的ActivityThread的main方法
public static void main(String[] args) {
//省略
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
//建立ActivityThread物件,並且呼叫attach方法
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
這裡主要就是對loop進行初始化,接下來再建立ActivityThread物件,呼叫它的attach方法:
private void attach(boolean system) {
if (!system) {
//省略
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
//省略
}
//省略
}
這裡主要應用端會獲取system server中的AMS物件IBinder物件,然後呼叫attachApplication(mAppThread)方法,這個attachApplication真正實現那是在ActivityManagerService:
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
//省略
attachApplicationLocked(thread, callingPid);
//省略
}
}
這裡又呼叫過載方法:private final boolean attachApplicationLocked(IApplicationThread thread,
int pid);
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
//省略
//跨程序呼叫,執行對應程序的Application的onCreate等方法
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
//省略。。
if (mStackSupervisor.attachApplicationLocked(app)) {
//省略。。
return true;
}
這裡呼叫StackSupervisor.attachApplicationLocked(app):
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
//省略
if (realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
//省略
return didSomething;
}
這裡又會呼叫到realStartActivityLocked方法:
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
//省略
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
//省略
return true;
}
這裡最後跨程序調回應用程序,ActivityThread的ApplicationThread的scheduleLaunchActivity方法,這個方法再進行Activtiy的onCreate等呼叫,這裡就不帶大家分析ActivityThread的相關內容了,因為ActivityThread中基本屬於應用層自己執行程式碼,而且相對不那麼複雜,自己完全可以分析,所以當作作業留給大家自己分析接下來的ActivityThread部分。
最後附上對應的流程總圖: