您的位置:首页 > 移动开发

Android M 6.0,关于ActivityThread和ApplicationThread的解析.

2016-12-03 10:24 239 查看
文章仅仅用于个人的学习记录,基本上内容都是网上各中资料,此处摘录过来以自己的理解学习方式记录一下。ActivityThread和ApplicationThread的理解在你阅读源代码尤其和进程启动,service、activity启动等相关的代码时,就能发现其重要性了。1、ActivityThread.在Android中它就代表了Android的主线程,注意是代表而不是说它就是一个Thread类,它是创建完新进程之后(肯定是在一个线程中啊),main函数被加载,然后执行一个loop的循环使当前线程进入消息循环,并且作为主线程。接下来还会初始化很多必要的属性.它的很多成员变量和内部类十分的重要,深入理解这些成员变量有助于我们进一步的认识Android系统的各个组件的交互。1.1、它的main函数如下.
publicstaticvoidmain(String[]args){
......
Looper.prepareMainLooper();
ActivityThreadthread=newActivityThread();//实例化这个类
thread.attach(false);//这个attach也很关键后面分析.
if(sMainThreadHandler==null){
sMainThreadHandler=thread.getHandler();//很重要mainHandler用于处理UI线程的各种信息
}
......
Looper.loop();
//可以看出来主线程也是在无限的循环的,异常退出循环的时候会报错.
thrownewRuntimeException("Mainthreadloopunexpectedlyexited");
}
[/code]注意此处虽然new出了ActivityThread的实例但是它的局部的啊,那我们怎么得到这个实例那?
privatestaticActivityThreadsCurrentActivityThread;
publicstaticActivityThreadcurrentActivityThread(){
returnsCurrentActivityThread;
}
privatevoidattach(booleansystem){
sCurrentActivityThread=this;
......//其它的我们后面专门分析.
}
[/code]通过currentActivityThread()的方法.1.2、finalApplicationThreadmAppThread=newApplicationThread();这个成员变量我们后面专门分析.它就是作为服务端,接收ActivityManagerService的指令并执行.是ActivityThread与AMS连接的桥梁.1.3、finalHmH=newH()这个H是继承自Handler的,它是个私有的内部类,其实就是主线程的Handler,通过这个Handler就可以往主线程的消息队列发消息如:启动Activity、service,接收广播等等,很多重要的工作.这个成员变量mH默认权限修饰符可以通过ActivityThread的如下方法来获得.
privateclassHextendsHandler{......}
finalHandlergetHandler(){
returnmH;
}
[/code]这个消息队列可以说是一个中转站,用来更好的分类管理各种类别的业务的处理,如AMS创建service,通过mAppThread这个binder对象的成员变量当中的方法,进而往消息队列中发送相应的消息,然后在不同的case中作出相应的处理.如:startservice()的流程最后.调用到ApplicationThread的scheduleCreateService(跨进程)
publicfinalvoidscheduleCreateService(IBindertoken,
ServiceInfoinfo,CompatibilityInfocompatInfo,intprocessState){
updateProcessState(processState,false);
CreateServiceDatas=newCreateServiceData();
s.token=token;
s.info=info;
s.compatInfo=compatInfo;
sendMessage(H.CREATE_SERVICE,s);
}
[/code]
caseCREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,"serviceCreate");
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
[/code]
privatevoidhandleCreateService(CreateServiceDatadata){
......
LoadedApkpackageInfo=getPackageInfoNoCheck(
data.info.applicationInfo,data.compatInfo);
Serviceservice=null;
try{
java.lang.ClassLoadercl=packageInfo.getClassLoader();
service=(Service)cl.loadClass(data.info.name).newInstance();
}catch(Exceptione){
......
}
try{
if(localLOGV)Slog.v(TAG,"Creatingservice"+data.info.name);
ContextImplcontext=ContextImpl.createAppContext(this,packageInfo);
context.setOuterContext(service);
Applicationapp=packageInfo.makeApplication(false,mInstrumentation);
service.attach(context,this,data.info.name,data.token,app,
ActivityManagerNative.getDefault());
service.onCreate();
mServices.put(data.token,service);
try{
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token,SERVICE_DONE_EXECUTING_ANON,0,0);
}catch(RemoteExceptione){
//nothingtodo.
}
}catch(Exceptione){
......
}
}
[/code]这样最终完成service的启动,调用到service的onCreate的方法,很多这样的调用模式,需要熟悉。这样我们就会发现ActivityThread中好多类似的重要的方法用于最终的事件处理.如下:
handleActivityConfigurationChanged()
handleBindApplication()
handleBindService()
handleCancelVisibleBehind()
handleConfigurationChanged()
handleCreateService()
handleDestroyActivity()
handleDispatchPackageBroadcast()
handleLaunchActivity()
handleLowMemory()
handleMessage()
handleNewIntent()
handlePauseActivity()
handleReceiver()
handleRelaunchActivity()
handleResumeActivity()
handleSendResult()
handleServiceArgs()
handleStopActivity()
handleStopService()
handleUnbindService()
[/code]光看名字都能感觉到这些函数的重要性,而这些函数有的又会调用到如下的系列函数完成最终的事件处理.
performDestroyActivity()
performDestroyActivity()
performLaunchActivity()
performNewIntents()
performPauseActivity()
performPauseActivity()
performRestartActivity()
performResumeActivity()
performStopActivity()
performStopActivityInner()
performUserLeavingActivity()
[/code]1.4、成员变量mActivities.它包含了当前进程的所有的activity,(一个进程对应一个ActivityThread)注意不是简单的把activity做了数据集合,而是封装成了ActivityClientRecord.finalArrayMap<IBinder,ActivityClientRecord>mActivities=newArrayMap<IBinder,ActivityClientRecord>()那么就需要看一下ActivityClientRecord了.
staticfinalclassActivityClientRecord{
IBindertoken;
intident;
Intentintent;
Stringreferrer;
IVoiceInteractorvoiceInteractor;
Bundlestate;
PersistableBundlepersistentState;
Activityactivity;
Windowwindow;
Activityparent;
StringembeddedID;
Activity.NonConfigurationInstanceslastNonConfigurationInstances;
booleanpaused;
booleanstopped;
booleanhideForNow;
ConfigurationnewConfig;
ConfigurationcreatedConfig;
ActivityClientRecordnextIdle;
ProfilerInfoprofilerInfo;
ActivityInfoactivityInfo;
CompatibilityInfocompatInfo;
LoadedApkpackageInfo;
List<ResultInfo>pendingResults;
List<ReferrerIntent>pendingIntents;
booleanstartsNotResumed;
booleanisForward;
intpendingConfigChanges;
booleanonlyLocalRequest;
ViewmPendingRemoveWindow;
WindowManagermPendingRemoveWindowManager;
ActivityClientRecord(){
parent=null;
embeddedID=null;
paused=false;
stopped=false;
hideForNow=false;
nextIdle=null;
}
......
publicbooleanisPersistable(){
returnactivityInfo.persistableMode==ActivityInfo.PERSIST_ACROSS_REBOOTS;
}
......
}
[/code]在ActivityThread当中最终通过performLaunchActivity()来完成Activity的启动.先只贴出要分析的代码.
privateActivityperformLaunchActivity(ActivityClientRecordr,IntentcustomIntent){
......//完成Activity的启动.
mActivities.put(r.token,r);
}
[/code]可以看到最终完成Activity在本进程中的启动的时候,会以ActivityClientRecord的成员变量token为key,以ActivityClientRecord为value.存入到mActivitys当中.这个token是一个IBinder的变量.(??最后补上)那么问题的关键就是ActivityClientRecord是怎么实例化然后传入过来的?我们在往上一层跟.
publicfinalActivitystartActivityNow(Activityparent,Stringid,
Intentintent,ActivityInfoactivityInfo,IBindertoken,Bundlestate,
Activity.NonConfigurationInstanceslastNonConfigurationInstances){
ActivityClientRecordr=newActivityClientRecord();
r.token=token;
r.ident=0;
r.intent=intent;
r.state=state;
r.parent=parent;
r.embeddedID=id;
r.activityInfo=activityInfo;
r.lastNonConfigurationInstances=lastNonConfigurationInstances;
......
returnperformLaunchActivity(r,null);
}
[/code]可以看到很多关键信息都是由调用给这个方法的类传入的,其实就是AMS.我们在分析Activity启动的时候会详细分析.相对非常重要的有token、intent、activityInfo等.尤其这个ActivityInfo包含了太多的Activity的信息.1.5、成员变量mServices它和mActivities类似的处理方式,里面也是包含了当前进程中所有的services,不过就是直接存放的当前Service的信息,没有封装=newArrayMap<IBinder,Service>();
privatevoidhandleCreateService(CreateServiceDatadata){
try{
......
mServices.put(data.token,service);
......
}catch(Exceptione){
......
}
}
[/code]也是最终完成startService的流程后,以key=CreateServiceData.token,Value=启动的Service.存入到mServices当中。那么问题又来了我们就需要看一下CreateServiceData怎么来的了.首先handleCreateService是由mH中的case走过来的.
caseCREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,"serviceCreate");
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
[/code]找到本类中发送消息的地方.
publicfinalvoidscheduleCreateService(IBindertoken,
ServiceInfoinfo,CompatibilityInfocompatInfo,intprocessState){
updateProcessState(processState,false);
CreateServiceDatas=newCreateServiceData();
s.token=token;
s.info=info;
s.compatInfo=compatInfo;
sendMessage(H.CREATE_SERVICE,s);
}
[/code]也同样可以看到CreateServiceData就是把一些关键的信息封装到了一起如:token、info等,这些在分析启动service的流程的时候一定要仔细.1.6、其它还有很多的成员变量如:ConfigurationmConfiguration;finalArrayList<Application>mAllApplications=newArrayList<Application>();finalArrayMap<String,WeakReference<LoadedApk>>mPackages=newArrayMap<String,WeakReference<LoadedApk>>();finalArrayMap<ProviderKey,ProviderClientRecord>mProviderMap=newArrayMap<ProviderKey,ProviderClientRecord>();finalArrayMap<IBinder,ProviderClientRecord>mLocalProviders=newArrayMap<IBinderProviderClientRecord>();还有很多的内部类如:staticfinalclassBindServiceData:用来封装使用bindeservice启动的时候的service的信息.staticfinalclassReceiverData:用来封装和广播处理相关的一些信息.finalclassProviderClientRecord:用来封装和Provider交互的一些信息staticfinalclassAppBindData:用来封装和Application交互时的一些信息.这些都不一一分析了.遇到的时候或者感兴趣的时候再去研究一下.1.7、最后我们再分析一下attach的方法.这个方法在新进程启动完毕后会在main方法中调用,这是一种调用方法,其实它还会在systemMain()当中调用并且传入的参数是true.它是由SystemServer.java调用的(没研究过这块的启动应该是系统的某个初始进程,没走Zygote)
privatevoidattach(booleansystem){
sCurrentActivityThread=this;
mSystemThread=system;
if(!system){
......
finalIActivityManagermgr=ActivityManagerNative.getDefault();
try{
mgr.attachApplication(mAppThread);//很关键.
}catch(RemoteExceptionex){
//Ignore
}
//Watchforgettingclosetoheaplimit.
......
}else{
//Don'tsetapplicationobjecthere--ifthesystemcrashes,
//wecan'tdisplayanalert,wejustwanttodiediedie.
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try{
mInstrumentation=newInstrumentation();
ContextImplcontext=ContextImpl.createAppContext(
this,getSystemContext().mPackageInfo);
mInitialApplication=context.mPackageInfo.makeApplication(true,null);
mInitialApplication.onCreate();
}catch(Exceptione){
thrownewRuntimeException(
"UnabletoinstantiateApplication():"+e.toString(),e);
}
}
ViewRootImpl.addConfigCallback(newComponentCallbacks2(){
@Override
publicvoidonConfigurationChanged(ConfigurationnewConfig){
synchronized(mResourcesManager){
......
sendMessage(H.CONFIGURATION_CHANGED,newConfig);.....
}
}
}
@Override
publicvoidonLowMemory(){
}
@Override
publicvoidonTrimMemory(intlevel){
}
});
}
[/code]此处我们重点关注非系统的的逻辑.是通过mgr.attachApplication(mAppThread)调用AMS的对应方法,(发现解锁Binder)以后真的是读代码各种顺.注意:mAppThread对象的传入.
@Override
publicfinalvoidattachApplication(IApplicationThreadthread){
synchronized(this){
intcallingPid=Binder.getCallingPid();
finallongorigId=Binder.clearCallingIdentity();
attachApplicationLocked(thread,callingPid);
Binder.restoreCallingIdentity(origId);
}
}
[/code]获得了正在Binder通信的客户端的uid然后和ApplicationThread对象作为参数传入到AMS的attachApplicationLocked中
privatefinalbooleanattachApplicationLocked(IApplicationThreadthread,
intpid){
//Findtheapplicationrecordthatisbeingattached...eithervia
//thepidifwearerunninginmultipleprocesses,orjustpullthe
//nextapprecordifweareemulatingprocesswithanonymousthreads.
ProcessRecordapp;
if(pid!=MY_PID&&pid>=0){
synchronized(mPidsSelfLocked){
app=mPidsSelfLocked.get(pid);//在整个启动进程的流程中在前面已经push进入
}
}else{
app=null;
}
if(app==null){
......
returnfalse;//为null的时候直接返回.
}
//正常第一次开启时此时还是null
if(app.thread!=null){
handleAppDiedLocked(app,true,true);
}
......
finalStringprocessName=app.processName;
......
//下面这个方法很关键,来时例化ProcessRecord的thread变量.它是一个IApplicationThread对象.
app.makeActive(thread,mProcessStats);//在这里实现的附着!
app.curAdj=app.setAdj=-100;
app.curSchedGroup=app.setSchedGroup=Process.THREAD_GROUP_DEFAULT;
app.forcingToForeground=null;
updateProcessForegroundLocked(app,false,false);
app.hasShownUi=false;
app.debugging=false;
app.cached=false;
app.killedByAm=false;
mHandler.removeMessages(PROC_START_TIMEOUT_MSG,app);
booleannormalMode=mProcessesReady||isAllowedWhileBooting(app.info);
List<ProviderInfo>providers=normalMode?generateApplicationProvidersLocked(app):null;
......
try{
......
thread.bindApplication(processName,appInfo,providers,app.instrumentationClass,
profilerInfo,app.instrumentationArguments,app.instrumentationWatcher,
app.instrumentationUiAutomationConnection,testMode,enableOpenGlTrace,
isRestrictedBackupMode||!normalMode,app.persistent,
newConfiguration(mConfiguration),app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
updateLruProcessLocked(app,false,null);
app.lastRequestedGc=app.lastLowMemory=SystemClock.uptimeMillis();
}catch(Exceptione){
......
returnfalse;
}
//Removethisrecordfromthelistofstartingapplications.
mPersistentStartingProcesses.remove(app);
if(DEBUG_PROCESSES&&mProcessesOnHold.contains(app))Slog.v(TAG,
"Attachapplicationlockedremovingonhold:"+app);
mProcessesOnHold.remove(app);
booleanbadApp=false;
booleandidSomething=false;
//Seeifthetopvisibleactivityiswaitingtoruninthisprocess...
if(normalMode){
.....
}
//Findanyservicesthatshouldberunninginthisprocess...
if(!badApp){
......
}
//Checkifanext-broadcastreceiverisinthisprocess...
if(!badApp&&isPendingBroadcastProcessLocked(pid)){
......
}
//Checkwhetherthenextbackupagentisinthisprocess...
if(!badApp&&mBackupTarget!=null&&mBackupTarget.appInfo.uid==app.uid){
......
}
if(badApp){
......
}
if(!didSomething){
......
}
returntrue;
}
[/code]在此处我们集中在为ProcessRecord的成员变量IApplicationThreadthread赋值的步骤,也就是调用ProcessRecord中的makeActive(thread,mProcessStats);
publicvoidmakeActive(IApplicationThread_thread,ProcessStatsServicetracker){//zy它就是赋值thread.
if(thread==null){
......
}
thread=_thread;
}
[/code]2、ApplicationThread.它是ActivityThread的私有内部类,也是一个Binder对象。在此处它是作为IApplicationThread对象的server端等待client端的请求然后进行处理,最大的client就是AMS.
privateclassApplicationThreadextendsApplicationThreadNative{
publicfinalvoidschedulePauseActivity(IBindertoken,booleanfinished,
booleanuserLeaving,intconfigChanges,booleandontReport){
......
}
publicfinalvoidscheduleStopActivity(IBindertoken,booleanshowWindow,
intconfigChanges){
......
}
publicfinalvoidscheduleLaunchActivity(Intentintent,IBindertoken,intident,
ActivityInfoinfo,ConfigurationcurConfig,CompatibilityInfocompatInfo,
Stringreferrer,IVoiceInteractorvoiceInteractor,intprocState,Bundlestate,
PersistableBundlepersistentState,List<ResultInfo>pendingResults,
List<ReferrerIntent>pendingNewIntents,booleannotResumed,booleanisForward,
ProfilerInfoprofilerInfo){
......
}
......
}
[/code]可以看出来它是继承自ApplicationThreadNative的,并且它内部有非常多的scheduleXXX的方法.以后看到thread调用这个方法就可以往这边找。我们先说一下这些方法,这些方法由外部的ActivityThread的binder远程代理对象调用最终走到这里.这些schedulexxx的方法会进一步的通过往外发送消息给mH这个消息队列.来做处理.比如:
publicfinalvoidscheduleCreateService(IBindertoken,
ServiceInfoinfo,CompatibilityInfocompatInfo,intprocessState){
updateProcessState(processState,false);
CreateServiceDatas=newCreateServiceData();
s.token=token;
s.info=info;
s.compatInfo=compatInfo;
sendMessage(H.CREATE_SERVICE,s);
}
[/code]比较重要的schedulexxx方法有:
schedulePauseActivity()
scheduleStopActivity()
scheduleResumeActivity()
scheduleSendResult()
scheduleLaunchActivity()
scheduleNewIntent()
scheduleDestroyActivity()
scheduleReceiver()
scheduleCreateService()
scheduleBindService()
scheduleUnbindService()
scheduleServiceArgs()
scheduleStopService()
bindApplication()
scheduleConfigurationChanged()
scheduleRegisteredReceiver()
scheduleInstallProvider()
还有很多dump信息的处理
[/code]这些方法放在此处眼熟,暂时没精力一个个分析,从名字也能看出大概的功能.接下来我们再看看ApplicationThreadNative,看这个函数的名字感觉就应该是被实现为了一个Binder对象。
/**{@hide}*/
publicabstractclassApplicationThreadNativeextendsBinder
implementsIApplicationThread{
//根据传入的不同参数决定返回不同的值.
staticpublicIApplicationThreadasInterface(IBinderobj){
if(obj==null){
returnnull;
}
IApplicationThreadin=
(IApplicationThread)obj.queryLocalInterface(descriptor);
if(in!=null){
returnin;
}
returnnewApplicationThreadProxy(obj);
}
publicApplicationThreadNative(){
attachInterface(this,descriptor);
}
@Override
publicbooleanonTransact(intcode,Parceldata,Parcelreply,intflags)
throwsRemoteException{
switch(code){
......
}
}
publicIBinderasBinder()
{
returnthis;
}
}
[/code]果不其然啊,并且还是先了业务接口IApplicationThread,非常标准的Binder模板.IApplicationThreadextendsIInterface它里面就是定义了非常多的通信的业务接口,也都是schedulexxx理解上对应到ApplicationThread那些方法.首先是提供了一个静态的方法asInterface()用来获取IApplicationThread的Binder对象或者Binder代理对象,其它进程跨进程调用时候当传入的是BinderProxy那么就会返回一个ApplicationThreadProxy对象并把BinderProxy传入它的构造.而一般在本进程中调用的时候,就直接返回当前IApplicationThread对象.然后就是onTransact()函数了,里面通过不同的code对应到不同的case,进而调用不同的schedulexxx的方法,最终调入到ApplicationThread中的schedulexxx.ApplicationThread这样就完成了作为服务端的构架,接下来就就是代理端的分析了.前面我们知道跨进程调用asInterface的时候返回的是ApplicationThreadProxy对象,该类位于ApplicationThreadNative.java文件当中,但是不是内部类,同文件而已.
classApplicationThreadProxyimplementsIApplicationThread{
privatefinalIBindermRemote;
publicApplicationThreadProxy(IBinderremote){
mRemote=remote;
}
publicfinalIBinderasBinder(){
returnmRemote;
}
publicfinalvoidschedulePauseActivity(IBindertoken,booleanfinished,
booleanuserLeaving,intconfigChanges,booleandontReport)throwsRemoteException{
Parceldata=Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
data.writeInt(finished?1:0);
data.writeInt(userLeaving?1:0);
data.writeInt(configChanges);
data.writeInt(dontReport?1:0);
mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION,data,null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
publicfinalvoidscheduleStopActivity(IBindertoken,booleanshowWindow,
intconfigChanges)throwsRemoteException{
......
}
......//一些列的schedulexxx
}
[/code]也是代理端的标准实现,实现了IApplicationThread接口,然后重写出接口中定义的业务方法,在每个方法中最终调用到了服务端的对应的schedulexxx方法中.通过mRemote变量和驱动去交互进而调用到server端,mRemote是一个BinderProxy对象.关于IApplicationThread的Binder相关实现,有个需要注意的它没有趣servicemanager中注册,走的是一个匿名的binder的方法,其实对于驱动来说都一样.暂时发现的是别的地方如AMS用的时候通过ActivityThread的接口获得到ApplicationThread的对象,然后传入到asInterface(),获取对应的IApplicationThread对象进行跨进程调用.3、Instrumentation.在android.app包下有Instrumentation这个类,这个类没有继承和实现其它的任何类,也没被其它的类继承.会在应用的任何代码执行前被实列化,用来监控系统组件与应用的交互过程,其实就是很多操作封装一下,由它来完成实现.Instrumentation另一个重要作用是提供Android组件单元测试每一个应用进程中只有唯一的Instrumentation,在ActivityThread中成员变量InstrumentationmInstrumentation,通过方法publicInstrumentationgetInstrumentation()来获得.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息