- 浏览: 21491782 次
- 性别:
- 来自: 杭州
最新评论
-
ZY199266:
配置文件还需要额外的配置ma
Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程 -
ZY199266:
我的一访问为什么是 /mavenwebdemo/WEB-I ...
Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程 -
lvgaga:
我又一个问题就是 如果像你的这种形式写。配置文件还需要额外的 ...
Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程 -
lvgaga:
我的一访问为什么是 /mavenwebdemo/WEB-I ...
Android 客户端通过内置API(HttpClient) 访问 服务器(用Spring MVC 架构) 返回的json数据全过程 -
y1210251848:
你的那个错误应该是项目所使用的目标框架不支持吧
log4net配置(web中使用log4net,把web.config放在单独的文件中)
Android应用程序进程启动过程的源代码分析
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文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalvoidstartProcessLocked(ProcessRecordapp,
- StringhostingType,StringhostingNameStr){
- ......
- try{
- intuid=app.info.uid;
- int[]gids=null;
- try{
- gids=mContext.getPackageManager().getPackageGids(
- app.info.packageName);
- }catch(PackageManager.NameNotFoundExceptione){
- ......
- }
- ......
- intdebugFlags=0;
- ......
- intpid=Process.start("android.app.ActivityThread",
- mSimpleProcessManagement?app.processName:null,uid,uid,
- gids,debugFlags,null);
- ......
- }catch(RuntimeExceptione){
- ......
- }
- }
- ......
- }
Step 2. Process.start
这个函数定义在frameworks/base/core/java/android/os/Process.java文件中:
- publicclassProcess{
- ......
- publicstaticfinalintstart(finalStringprocessClass,
- finalStringniceName,
- intuid,intgid,int[]gids,
- intdebugFlags,
- String[]zygoteArgs)
- {
- if(supportsProcesses()){
- try{
- returnstartViaZygote(processClass,niceName,uid,gid,gids,
- debugFlags,zygoteArgs);
- }catch(ZygoteStartFailedExex){
- ......
- }
- }else{
- ......
- return0;
- }
- }
- ......
- }
- jbooleanandroid_os_Process_supportsProcesses(JNIEnv*env,jobjectclazz)
- {
- returnProcessState::self()->supportsProcesses();
- }
ProcessState::supportsProcesses函数定义在frameworks/base/libs/binder/ProcessState.cpp文件中:
- boolProcessState::supportsProcesses()const
- {
- returnmDriverFD>=0;
- }
回到Process.start函数中,它调用startViaZygote函数进一步操作。
Step 3.Process.startViaZygote
这个函数定义在frameworks/base/core/java/android/os/Process.java文件中:
- publicclassProcess{
- ......
- privatestaticintstartViaZygote(finalStringprocessClass,
- finalStringniceName,
- finalintuid,finalintgid,
- finalint[]gids,
- intdebugFlags,
- String[]extraArgs)
- throwsZygoteStartFailedEx{
- intpid;
- synchronized(Process.class){
- ArrayList<String>argsForZygote=newArrayList<String>();
- //--runtime-init,--setuid=,--setgid=,
- //and--setgroups=mustgofirst
- argsForZygote.add("--runtime-init");
- argsForZygote.add("--setuid="+uid);
- argsForZygote.add("--setgid="+gid);
- if((debugFlags&Zygote.DEBUG_ENABLE_SAFEMODE)!=0){
- argsForZygote.add("--enable-safemode");
- }
- if((debugFlags&Zygote.DEBUG_ENABLE_DEBUGGER)!=0){
- argsForZygote.add("--enable-debugger");
- }
- if((debugFlags&Zygote.DEBUG_ENABLE_CHECKJNI)!=0){
- argsForZygote.add("--enable-checkjni");
- }
- if((debugFlags&Zygote.DEBUG_ENABLE_ASSERT)!=0){
- argsForZygote.add("--enable-assert");
- }
- //TODOoptionallyenabledebuger
- //argsForZygote.add("--enable-debugger");
- //--setgroupsisacomma-separatedlist
- if(gids!=null&&gids.length>0){
- StringBuildersb=newStringBuilder();
- sb.append("--setgroups=");
- intsz=gids.length;
- for(inti=0;i<sz;i++){
- if(i!=0){
- sb.append(',');
- }
- sb.append(gids[i]);
- }
- argsForZygote.add(sb.toString());
- }
- if(niceName!=null){
- argsForZygote.add("--nice-name="+niceName);
- }
- argsForZygote.add(processClass);
- if(extraArgs!=null){
- for(Stringarg:extraArgs){
- argsForZygote.add(arg);
- }
- }
- pid=zygoteSendArgsAndGetPid(argsForZygote);
- }
- }
- ......
- }
Step 4. Process.zygoteSendAndGetPid
这个函数定义在frameworks/base/core/java/android/os/Process.java文件中:
- publicclassProcess{
- ......
- privatestaticintzygoteSendArgsAndGetPid(ArrayList<String>args)
- throwsZygoteStartFailedEx{
- intpid;
- openZygoteSocketIfNeeded();
- try{
- /**
- *Seecom.android.internal.os.ZygoteInit.readArgumentList()
- *Presentlythewireformattothezygoteprocessis:
- *a)acountofarguments(argc,inessence)
- *b)anumberofnewline-separatedargumentstringsequaltocount
- *
- *Afterthezygoteprocessreadstheseitwillwritethepidof
- *thechildor-1onfailure.
- */
- sZygoteWriter.write(Integer.toString(args.size()));
- sZygoteWriter.newLine();
- intsz=args.size();
- for(inti=0;i<sz;i++){
- Stringarg=args.get(i);
- if(arg.indexOf('\n')>=0){
- thrownewZygoteStartFailedEx(
- "embeddednewlinesnotallowed");
- }
- sZygoteWriter.write(arg);
- sZygoteWriter.newLine();
- }
- sZygoteWriter.flush();
- //Shouldtherebeatimeoutonthis?
- pid=sZygoteInputStream.readInt();
- if(pid<0){
- thrownewZygoteStartFailedEx("fork()failed");
- }
- }catch(IOExceptionex){
- ......
- }
- returnpid;
- }
- ......
- }
- publicclassProcess{
- ......
- /**
- *TriestoopensockettoZygoteprocessifnotalreadyopen.If
- *alreadyopen,doesnothing.Mayblockandretry.
- */
- privatestaticvoidopenZygoteSocketIfNeeded()
- throwsZygoteStartFailedEx{
- intretryCount;
- if(sPreviousZygoteOpenFailed){
- /*
- *Ifwe'vefailedbefore,expectthatwe'llfailagainand
- *don'tpauseforretries.
- */
- retryCount=0;
- }else{
- retryCount=10;
- }
- /*
- *Seebug#811181:Sometimesruntimecanmakeitupbeforezygote.
- *Really,we'dliketodosomethingbettertoavoidthiscondition,
- *butfornowjustwaitabit...
- */
- for(intretry=0
- ;(sZygoteSocket==null)&&(retry<(retryCount+1))
- ;retry++){
- if(retry>0){
- try{
- Log.i("Zygote","Zygotenotupyet,sleeping...");
- Thread.sleep(ZYGOTE_RETRY_MILLIS);
- }catch(InterruptedExceptionex){
- //shouldneverhappen
- }
- }
- try{
- sZygoteSocket=newLocalSocket();
- sZygoteSocket.connect(newLocalSocketAddress(ZYGOTE_SOCKET,
- LocalSocketAddress.Namespace.RESERVED));
- sZygoteInputStream
- =newDataInputStream(sZygoteSocket.getInputStream());
- sZygoteWriter=
- newBufferedWriter(
- newOutputStreamWriter(
- sZygoteSocket.getOutputStream()),
- 256);
- Log.i("Zygote","Process:zygotesocketopened");
- sPreviousZygoteOpenFailed=false;
- break;
- }catch(IOExceptionex){
- ......
- }
- }
- ......
- }
- ......
- }
Step 5.ZygoteInit.runSelectLoopMode
这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:
- publicclassZygoteInit{
- ......
- /**
- *Runsthezygoteprocess'sselectloop.Acceptsnewconnectionsas
- *theyhappen,andreadscommandsfromconnectionsonespawn-request's
- *worthatatime.
- *
- *@throwsMethodAndArgsCallerinachildprocesswhenamain()should
- *beexecuted.
- */
- privatestaticvoidrunSelectLoopMode()throwsMethodAndArgsCaller{
- ArrayList<FileDescriptor>fds=newArrayList();
- ArrayList<ZygoteConnection>peers=newArrayList();
- FileDescriptor[]fdArray=newFileDescriptor[4];
- fds.add(sServerSocket.getFileDescriptor());
- peers.add(null);
- intloopCount=GC_LOOP_COUNT;
- while(true){
- intindex;
- /*
- *Callgc()beforeweblockinselect().
- *It'sworkthathastobedoneanyway,andit'sbetter
- *toavoidmakingeverychilddoit.Itwillalso
- *madvise()anyfreememoryasaside-effect.
- *
- *Don'tcalliteverytime,becausewalkingtheentire
- *heapisalotofoverheadtofreeafewhundredbytes.
- */
- if(loopCount<=0){
- gc();
- loopCount=GC_LOOP_COUNT;
- }else{
- loopCount--;
- }
- try{
- fdArray=fds.toArray(fdArray);
- index=selectReadable(fdArray);
- }catch(IOExceptionex){
- thrownewRuntimeException("Errorinselect()",ex);
- }
- if(index<0){
- thrownewRuntimeException("Errorinselect()");
- }elseif(index==0){
- ZygoteConnectionnewPeer=acceptCommandPeer();
- peers.add(newPeer);
- fds.add(newPeer.getFileDesciptor());
- }else{
- booleandone;
- done=peers.get(index).runOnce();
- if(done){
- peers.remove(index);
- fds.remove(index);
- }
- }
- }
- }
- ......
- }
- done=peers.get(index).runOnce();
Step 6.ZygoteConnection.runOnce
这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中:
- classZygoteConnection{
- ......
- booleanrunOnce()throwsZygoteInit.MethodAndArgsCaller{
- Stringargs[];
- ArgumentsparsedArgs=null;
- FileDescriptor[]descriptors;
- try{
- args=readArgumentList();
- descriptors=mSocket.getAncillaryFileDescriptors();
- }catch(IOExceptionex){
- ......
- returntrue;
- }
- ......
- /**thestderrofthemostrecentrequest,ifavail*/
- PrintStreamnewStderr=null;
- if(descriptors!=null&&descriptors.length>=3){
- newStderr=newPrintStream(
- newFileOutputStream(descriptors[2]));
- }
- intpid;
- try{
- parsedArgs=newArguments(args);
- applyUidSecurityPolicy(parsedArgs,peer);
- applyDebuggerSecurityPolicy(parsedArgs);
- applyRlimitSecurityPolicy(parsedArgs,peer);
- applyCapabilitiesSecurityPolicy(parsedArgs,peer);
- int[][]rlimits=null;
- if(parsedArgs.rlimits!=null){
- rlimits=parsedArgs.rlimits.toArray(intArray2d);
- }
- pid=Zygote.forkAndSpecialize(parsedArgs.uid,parsedArgs.gid,
- parsedArgs.gids,parsedArgs.debugFlags,rlimits);
- }catch(IllegalArgumentExceptionex){
- ......
- }catch(ZygoteSecurityExceptionex){
- ......
- }
- if(pid==0){
- //inchild
- handleChildProc(parsedArgs,descriptors,newStderr);
- //shouldneverhappen
- returntrue;
- }else{/*pid!=0*/
- //inparent...pidof<0meansfailure
- returnhandleParentProc(pid,descriptors,parsedArgs);
- }
- }
- ......
- }
- pid=Zygote.forkAndSpecialize(parsedArgs.uid,parsedArgs.gid,
- parsedArgs.gids,parsedArgs.debugFlags,rlimits);
- if(pid==0){
- //inchild
- handleChildProc(parsedArgs,descriptors,newStderr);
- //shouldneverhappen
- returntrue;
- }else{/*pid!=0*/
- ......
- }
Step 7.ZygoteConnection.handleChildProc
这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java文件中:
- classZygoteConnection{
- ......
- privatevoidhandleChildProc(ArgumentsparsedArgs,
- FileDescriptor[]descriptors,PrintStreamnewStderr)
- throwsZygoteInit.MethodAndArgsCaller{
- ......
- if(parsedArgs.runtimeInit){
- RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
- }else{
- ......
- }
- }
- ......
- }
Step 8.RuntimeInit.zygoteInit
这个函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:
- publicclassRuntimeInit{
- ......
- publicstaticfinalvoidzygoteInit(String[]argv)
- throwsZygoteInit.MethodAndArgsCaller{
- //TODO:Doingthishereworks,butitseemskindofarbitrary.Find
- //abetterplace.Thegoalistosetitupforapplications,butnot
- //toolslikeam.
- System.setOut(newAndroidPrintStream(Log.INFO,"System.out"));
- System.setErr(newAndroidPrintStream(Log.WARN,"System.err"));
- commonInit();
- zygoteInitNative();
- intcurArg=0;
- for(/*curArg*/;curArg<argv.length;curArg++){
- Stringarg=argv[curArg];
- if(arg.equals("--")){
- curArg++;
- break;
- }elseif(!arg.startsWith("--")){
- break;
- }elseif(arg.startsWith("--nice-name=")){
- StringniceName=arg.substring(arg.indexOf('=')+1);
- Process.setArgV0(niceName);
- }
- }
- if(curArg==argv.length){
- Slog.e(TAG,"MissingclassnameargumenttoRuntimeInit!");
- //lettheprocessexit
- return;
- }
- //Remainingargumentsarepassedtothestartclass'sstaticmain
- StringstartClass=argv[curArg++];
- String[]startArgs=newString[argv.length-curArg];
- System.arraycopy(argv,curArg,startArgs,0,startArgs.length);
- invokeStaticMain(startClass,startArgs);
- }
- ......
- }
我们先来看一下zygoteInitNative函数的调用过程,然后再回到RuntimeInit.zygoteInit函数中来,看看它是如何调用android.app.ActivityThread类的main函数的。
step 9.RuntimeInit.zygoteInitNative
这个函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:
- publicclassRuntimeInit{
- ......
- publicstaticfinalnativevoidzygoteInitNative();
- ......
- }
- staticvoidcom_android_internal_os_RuntimeInit_zygoteInit(JNIEnv*env,jobjectclazz)
- {
- gCurRuntime->onZygoteInit();
- }
这里它调用了全局变量gCurRuntime的onZygoteInit函数,这个全局变量的定义在frameworks/base/core/jni/AndroidRuntime.cpp文件开头的地方:
- staticAndroidRuntime*gCurRuntime=NULL;
- AndroidRuntime::AndroidRuntime()
- {
- ......
- assert(gCurRuntime==NULL);//oneperprocess
- gCurRuntime=this;
- }
- intmain(intargc,constchar*constargv[])
- {
- ......
- AppRuntimeruntime;
- ......
- }
- classAppRuntime:publicAndroidRuntime
- {
- ......
- };
Step 10.AppRuntime.onZygoteInit
这个函数定义在frameworks/base/cmds/app_process/app_main.cpp文件中:
- classAppRuntime:publicAndroidRuntime
- {
- ......
- virtualvoidonZygoteInit()
- {
- sp<ProcessState>proc=ProcessState::self();
- if(proc->supportsProcesses()){
- LOGV("Appprocess:startingthreadpool.\n");
- proc->startThreadPool();
- }
- }
- ......
- };
Step 11.ProcessState.startThreadPool
这个函数定义在frameworks/base/libs/binder/ProcessState.cpp文件中:
- voidProcessState::startThreadPool()
- {
- AutoMutex_l(mLock);
- if(!mThreadPoolStarted){
- mThreadPoolStarted=true;
- spawnPooledThread(true);
- }
- }
Step 12.ProcessState.spawnPooledThread
这个函数定义在frameworks/base/libs/binder/ProcessState.cpp文件中:
- voidProcessState::spawnPooledThread(boolisMain)
- {
- if(mThreadPoolStarted){
- int32_ts=android_atomic_add(1,&mThreadPoolSeq);
- charbuf[32];
- sprintf(buf,"BinderThread#%d",s);
- LOGV("Spawningnewpooledthread,name=%s\n",buf);
- sp<Thread>t=newPoolThread(isMain);
- t->run(buf);
- }
- }
Step 13.PoolThread.threadLoop
这个函数定义在frameworks/base/libs/binder/ProcessState.cpp文件中:
- classPoolThread:publicThread
- {
- public:
- PoolThread(boolisMain)
- :mIsMain(isMain)
- {
- }
- protected:
- virtualboolthreadLoop()
- {
- IPCThreadState::self()->joinThreadPool(mIsMain);
- returnfalse;
- }
- constboolmIsMain;
- };
Step 14.IPCThreadState.joinThreadPool
这个函数定义在frameworks/base/libs/binder/IPCThreadState.cpp文件中:
- voidIPCThreadState::joinThreadPool(boolisMain)
- {
- ......
- mOut.writeInt32(isMain?BC_ENTER_LOOPER:BC_REGISTER_LOOPER);
- ......
- status_tresult;
- do{
- int32_tcmd;
- ......
- //nowgetthenextcommandtobeprocessed,waitingifnecessary
- result=talkWithDriver();
- if(result>=NO_ERROR){
- size_tIN=mIn.dataAvail();
- if(IN<sizeof(int32_t))continue;
- cmd=mIn.readInt32();
- ......
- result=executeCommand(cmd);
- }
- ......
- }while(result!=-ECONNREFUSED&&result!=-EBADF);
- ......
- mOut.writeInt32(BC_EXIT_LOOPER);
- talkWithDriver(false);
- }
- mOut.writeInt32(isMain?BC_ENTER_LOOPER:BC_REGISTER_LOOPER);
- result=talkWithDriver();
- result=executeCommand(cmd);
- mOut.writeInt32(BC_EXIT_LOOPER);
- talkWithDriver(false);
Step 15. talkWithDriver
这个函数定义在frameworks/base/libs/binder/IPCThreadState.cpp文件中:
- status_tIPCThreadState::talkWithDriver(booldoReceive)
- {
- ......
- binder_write_readbwr;
- //Isthereadbufferempty?
- constboolneedRead=mIn.dataPosition()>=mIn.dataSize();
- //Wedon'twanttowriteanythingifwearestillreading
- //fromdataleftintheinputbufferandthecaller
- //hasrequestedtoreadthenextdata.
- constsize_toutAvail=(!doReceive||needRead)?mOut.dataSize():0;
- bwr.write_size=outAvail;
- bwr.write_buffer=(longunsignedint)mOut.data();
- //Thisiswhatwe'llread.
- if(doReceive&&needRead){
- bwr.read_size=mIn.dataCapacity();
- bwr.read_buffer=(longunsignedint)mIn.data();
- }else{
- bwr.read_size=0;
- }
- ......
- //Returnimmediatelyifthereisnothingtodo.
- if((bwr.write_size==0)&&(bwr.read_size==0))returnNO_ERROR;
- bwr.write_consumed=0;
- bwr.read_consumed=0;
- status_terr;
- do{
- ......
- #ifdefined(HAVE_ANDROID_OS)
- if(ioctl(mProcess->mDriverFD,BINDER_WRITE_READ,&bwr)>=0)
- err=NO_ERROR;
- else
- err=-errno;
- #else
- err=INVALID_OPERATION;
- #endif
- ......
- }
- }while(err==-EINTR);
- ....
- if(err>=NO_ERROR){
- if(bwr..write_consumed>0){
- if(bwr.write_consumed<(ssize_t)mOut.dataSize())
- mOut.remove(0,bwr.write_consumed);
- else
- mOut.setDataSize(0);
- }
- if(bwr.read_consumed>0){
- mIn.setDataSize(bwr.read_consumed);
- mIn.setDataPosition(0);
- }
- ......
- returnNO_ERROR;
- }
- returnerr;
- }
- ioctl(mProcess->mDriverFD,BINDER_WRITE_READ,&bwr)
细心的读者可能会发现,从Step 1到Step 9,都是在Android应用程序框架层运行的,而从Step 10到Step 15,都是在Android系统运行时库层运行的,这两个层次中的Binder进程间通信机制的接口一个是用Java来实现的,而别一个是用C++来实现的,这两者是如何协作的呢?这就是通过JNI层来实现的了,具体可以参考Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析一文。
回到Step 8中的RuntimeInit.zygoteInit函数中,在初始化完成Binder进程间通信机制的基础设施后,它接着就要进入进程的入口函数了。
Step 16.RuntimeInit.invokeStaticMain
这个函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:
- publicclassZygoteInit{
- ......
- staticvoidinvokeStaticMain(ClassLoaderloader,
- StringclassName,String[]argv)
- throwsZygoteInit.MethodAndArgsCaller{
- Class<?>cl;
- try{
- cl=loader.loadClass(className);
- }catch(ClassNotFoundExceptionex){
- ......
- }
- Methodm;
- try{
- m=cl.getMethod("main",newClass[]{String[].class});
- }catch(NoSuchMethodExceptionex){
- ......
- }catch(SecurityExceptionex){
- ......
- }
- intmodifiers=m.getModifiers();
- ......
- /*
- *ThisthrowgetscaughtinZygoteInit.main(),whichresponds
- *byinvokingtheexception'srun()method.Thisarrangement
- *clearsupallthestackframesthatwererequiredinsetting
- *uptheprocess.
- */
- thrownewZygoteInit.MethodAndArgsCaller(m,argv);
- }
- ......
- }
- cl=loader.loadClass(className);
- m=cl.getMethod("main",newClass[]{String[].class});
我们看看ZygoteInit.main函数在捕获到这个异常的时候做了什么事:
- publicclassZygoteInit{
- ......
- publicstaticvoidmain(Stringargv[]){
- try{
- ......
- }catch(MethodAndArgsCallercaller){
- caller.run();
- }catch(RuntimeExceptionex){
- ......
- }
- }
- ......
- }
- publicclassZygoteInit{
- ......
- publicstaticclassMethodAndArgsCallerextendsException
- implementsRunnable{
- /**methodtocall*/
- privatefinalMethodmMethod;
- /**argumentarray*/
- privatefinalString[]mArgs;
- publicMethodAndArgsCaller(Methodmethod,String[]args){
- mMethod=method;
- mArgs=args;
- }
- publicvoidrun(){
- try{
- mMethod.invoke(null,newObject[]{mArgs});
- }catch(IllegalAccessExceptionex){
- ......
- }catch(InvocationTargetExceptionex){
- ......
- }
- }
- }
- ......
- }
- mMethod.invoke(null,newObject[]{mArgs});
Step 17.ActivityThread.main
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- publicfinalclassActivityThread{
- ......
- publicstaticfinalvoidmain(String[]args){
- SamplingProfilerIntegration.start();
- Process.setArgV0("<pre-initialized>");
- Looper.prepareMainLooper();
- if(sMainThreadHandler==null){
- sMainThreadHandler=newHandler();
- }
- ActivityThreadthread=newActivityThread();
- thread.attach(false);
- if(false){
- Looper.myLooper().setMessageLogging(new
- LogPrinter(Log.DEBUG,"ActivityThread"));
- }
- Looper.loop();
- if(Process.supportsProcesses()){
- thrownewRuntimeException("Mainthreadloopunexpectedlyexited");
- }
- thread.detach();
- Stringname=(thread.mInitialApplication!=null)
- ?thread.mInitialApplication.getPackageName()
- :"<unknown>";
- Slog.i(TAG,"Mainthreadof"+name+"isnowexiting");
- }
- ......
- }
- ActivityThreadthread=newActivityThread();
- Looper.loop();
至此,Android应用程序进程启动过程的源代码就分析完成了,它除了指定新的进程的入口函数是ActivityThread的main函数之外,还为进程内的Binder对象提供了Binder进程间通信机制的基础设施,由此可见,Binder进程间通信机制在Android系统中是何等的重要,而且是无处不在,想进一步学习Android系统的Binder进程间通信机制,请参考Android进程间通信(IPC)机制Binder简要介绍和学习计划一文。
相关推荐
Android应用程序进程启动过程的源代码分析.pdf
Android应用程序绑定服务(bindService)的过程源代码分析UML.jpg,Android应用程序进程启动过程的源代码分析uml.jpg,Android应用程序内部启动Activity过程(startActivity)的源代码分析 UML.jpg,Android应用程序...
在Android系统中,应用程序是由Activity组成的,因此,应用程序的启动过程实际上就是应用程序中的默认Activity的启动过程,本文将详细分析应用程序框架层的源代码,了解Android应用程序的启动过程。在上一篇文章...
第12章 Android应用程序进程的启动过程 12.1 应用程序进程的创建过程 12.2 Binder线程池的启动过程 12.3 消息循环的创建过程 第13章 Android应用程序的消息处理机制 13.1 创建线程消息队列 13.2 线程...
第12章 Android应用程序进程的启动过程 第13章 Android应用程序的消息处理机制 第14章 Android应用程序的键盘消息处理机制 第15章 Android应用程序线程的消息循环模型 第16章 Android应用程序的安装和显示过程
第12章 Android应用程序进程的启动过程 12.1 应用程序进程的创建过程 12.2 Binder线程池的启动过程 12.3 消息循环的创建过程 第13章 Android应用程序的消息处理机制 13.1 创建线程消息队列 13.2 线程消息循环...
3.1 Android应用程序的组成部分 43 3.2 程序清单简介 44 3.3 使用清单编辑器 47 3.4 Android应用程序生命周期 48 3.5 理解应用程序的优先级和进程状态 49 3.6 分离资源 50 3.6.1 创建资源 50 3.6.2 使用资源...
Android系统源代码情景分析光盘资料 目录 第1篇初识Android系统 第1章 准备知识................................................................ 2 1.1 Linux内核参考书籍......................................
《Android移动应用开发(第3版)卷Ⅰ:基础篇》涵盖了Android开发从概念、技术到市场推广应用的全部主题,内容包括Android平台概览、Android应用程序设计精髓、Android用户界面设计精髓、Android应用程序设计精髓、...
第3章介绍应用程序进程启动过程。 第4章介绍四大组件的工作过程,包括根Activity的启动过程,Service的启动和绑定过程,广播的注册、发送和接收过程,Content Provider的启动过程。 第5章从源码角度分析上下文...
分析Android Activity的启动过程 对于Android Activity 的启动过程...根Activity一般就是指我们项目中的MainActivity,代表了一个android应用程序,一般也是在一个新的进程中启动起来。在Android系统中,所有的Activi
读者可以在自己的应用程序中随意使用源代码。 关于“快速阅读指南” 虽然大多数作者都希望读者阅读他们书中的每一句话,但我知道你可能不想这样做。你只希望阅读能够解决手头问题的部分,而在需要解决其他...
360新版特性界面源代码.rar aidl跨进程调用.rar ...Android模仿乐淘的应用程序分析源码.zip android电话、短信黑白名单拦截、电话录音.rar Android系统源码获取及编译.zip android项目实例 商业项目源代码.rar
Android 原生守护进程Android 应用程序的本机守护进程,当它消失时自动启动您的服务。构建源您必须在您的机器上安装 。 将 C 源文件 (daemon.c) 和 Android.mk 文件复制到您的项目目录中。 在您的项目目录中,运行...
《Android开发案例驱动教程》 配套代码。 注: 由于第12,13,14章代码太大,无法上传到一个包中。 这三节代码会放到其他压缩包中。 作者:关东升,赵志荣 Java或C++程序员转变成为Android程序员 采用案例驱动模式...
13.2.3 使用am工具启动android应用程序 306 13.3 android应用程序示例 308 13.3.1 helloactivity程序 308 13.3.2 helloactivity的源代码结构 308 13.3.3 helloactivity的编译结构(源代码开发) 312 13.3.4 ...
- 进程管理:列出系统中正在运行的程序;演示杀死软件 - 窗口小部件:添加桌面; - 流量统计:模拟器并不支持,在真机上才能演示,只做个UI效果; - 手机杀毒:检查手机安装的软件,发现那个是病毒,提醒用户就杀掉...
第13章“Android应用程序概述及框架”,介绍Android应用程序层的基本概念和应用程序框架,这部分内容是Android自下而上的第4个层次,可以基于源代码或者SDK开发,它们之间的差别非常小。 第14章“Android应用...
每个 Android 应用程序都在 Dalvik VM 的一个实例中运行,这个实例驻留在一个由 Linux 内核管理的进程中,如下图所示。 图 2. Dalvik VM Android 应用程序由一个或多个组件组成: 活动 具有可视 UI 的应用...