版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
本文格式为Word版,下载可任意编辑——Android系统Activity窗口启动过程在Android系统中,一个Activity对应一个应用程序窗口,任何一个Activity的启动都是由AMS服务和应用程序进程相互协同来完成的。AMS服务统一调度系统中所有进程的Activity启动,而每个Activity的启动过程则由其所属进程来完成。AMS服务通过realStartActivityLocked函数来通知应用程序进程启动某个Activity:frameworks/base/services/java/com/android/server/am/ActivityStack.java
finalbooleanrealStartActivityLocked(ActivityRecordr,ProcessRecordapp,booleanandResume,booleancheckConfig)throwsRemoteException{...//系统参数发送变化,通知Activityif(checkConfig){①Configurationconfig=mService.mWindowManager.updateOrientationFromAppTokens(mService.mConfiguration,r.mayFreezeScreenLocked(app)?r.appToken:null);mService.updateConfigurationLocked(config,r,false,false);}
//将进程描述符设置到启动的Activity描述符中r.app=app;
app.waitingToKill=null;//将启动的Activity添加到进程启动的Activity列表中intidx=app.activities.indexOf(r);if(idxpendingResults,ListpendingNewIntents,booleannotResumed,booleanisForward,StringprofileName,ParcelFileDescriptorprofileFd,booleanautoStopProfiler){//将AMS服务传过来的参数封装为ActivityClientRecord对象ActivityClientRecordr=newActivityClientRecord();r.token=token;r.ident=ident;ent=intent;r.activityInfo=info;patInfo=compatInfo;r.state=state;r.pendingResults=pendingResults;r.pendingIntents=pendingNewIntents;r.startsNotResumed=notResumed;r.isForward=isForward;fileFile=profileName;fileFd=profileFd;r.autoStopProfiler=autoStopProfiler;updatePendingConfiguration(curConfig);//使用异步消息方式实现Activity的启动queueOrSendMessage(H.LAUNCH_ACTIVITY,r);}
参数token从AMS服务端经过Binder传输到应用程序进程后,变为IApplicationToken的Binder代理对象,类型为IApplicationToken.Proxy,这是由于AMS和应用程序运行在不同的进程中。
通过queueOrSendMessage函数将Binder跨进程调用转换为应用程序进程中的异步消息处理frameworks/base/core/java/android/app/ActivityThread.java
privateclassHextendsHandler{publicvoidhandleMessage(Messagemsg){switch(msg.what){caseLAUNCH_ACTIVITY:{getPackageInfoNoCheck(r.activityInfo.applicationInfo,patInfo);
LAUNCH_ACTIVITY消息在应用程序主线程消息循环中得四处理,应用程序通过
handleLaunchActivity函数来启动Activity。到此AMS服务就完成了Activity的调度任务,将Activity的启动过程完全交给了应用程序进程来完成。frameworks/base/core/java/android/app/ActivityThread.java
privatevoidhandleLaunchActivity(ActivityClientRecordr,IntentcustomIntent){//主线程空闲时会定时执行垃圾回收,主线程当前要完成启动Activity的任务,因此这里先暂停GCunscheduleGcIdler();if(fileFd!=null){mProfiler.setProfiler(fileFile,fileFd);mProfiler.startProfiling();mProfiler.autoStopProfiler=r.autoStopProfiler;}//Makesurewearerunningwiththemostrecentconfig.①handleConfigurationChanged(null,null);//创立Activity②Activitya=performLaunchActivity(r,customIntent);if(a!=null){r.createdConfig=newConfiguration(mConfiguration);BundleoldState=r.state;
performLaunchActivity
应用程序进程通过performLaunchActivity函数将即将要启动的Activity加载到当前进程空间来,同时为启动Activity做准备。
frameworks/base/core/java/android/app/ActivityThread.java
privateActivityperformLaunchActivity(ActivityClientRecordr,IntentcustomIntent){ActivityInfoaInfo=r.activityInfo;if(r.packageInfo==null){//通过Activity所在的应用程序信息及该Activity对应的CompatibilityInfo信息从PMS服务中查询当前Activity的包信息r.packageInfo=getPackageInfo(aInfo.applicationInfo,
patInfo,Context.CONTEXT_INCLUDE_CODE);}//获取当前Activity的组件信息ComponentNamecomponent=ent.getComponent();if(component==null){component=
//启动Ac
ent.resolveActivity(mInitialApplication.getPackageManager());ComponentName(r.activityInfo.packageName,r.activityInfo.targetActivity);}//通过类反射方式加载即将启动的ActivityActivityactivity=null;try{ent);StrictMode.incrementExpectedActivityCount(activity.getClass());ent.setExtrasClassLoader(cl);if(r.state!=null){r.state.setClassLoader(cl);ent
java.lang
}
}
mInstrumentation);if(activity!=null){//为当前Activity创立上下文对象ContextImplContextImplappContext=newContextImpl();//上下文初始化③appContext.init(r.packageInfo,r.token,this);appContext.setOuterContext(activity);前启动的Activity和上下文ContextImpl、Application绑定r.lastNonConfigurationInstances,config);...ActivityClientRecord为Activity在应用程序进程中的描述符mActivities.put(r.token,r);}catch(SuperNotCalledExceptione){...}returnactivity;}
在该函数中,首先通过PMS服务查找到即将启动的Activity的包名信息,然后通过类反射方式创立一个该Activity实例,同时为应用程序启动的每一个Activity创立一个LoadedApk实例对象,应用程序进程中创立的所有LoadedApk对象保存在ActivityThread的成员变量mPackages中。接着通过LoadedApk对象的makeApplication函数,使用单例模式创立Application对象,因此在android应用程序进程中有且只有一个Application实例。然后为当前启动的Activity创立一个ContextImpl上下文对象,并初始化该上下文,到此我们可以知道,启动一个Activity需要以下对象:1)XXActivity对象,需要启动的Activity;
2)LoadedApk对象,每个启动的Activity都拥有属于自身的LoadedApk对象;3)ContextImpl对象,每个启动的Activity都拥有属于自身的ContextImpl对象;
4)Application对象,应用程序进程中有且只有一个实例,和Activity是一对多的关系;加载Activity类
publicActivitynewActivity(ClassLoadercl,StringclassName,Intentintent)throwsInstantiationException,
C④activi/r.activi
IllegalAccessException,ClassNotFoundException{
return(Activity)cl.loadClass(className).newInstance();}
这里通过类反射的方式来加载要启动的Activity实例对象。LoadedApk构造过程
首先介绍一下LoadedApk对象的构造过程:
frameworks/base/core/java/android/app/ActivityThread.java
publicfinalLoadedApkgetPackageInfo(StringpackageName,CompatibilityInfocompatInfo,intflags){synchronized(mPackages){//通过Activity的包名从对应的成员变量中查找LoadedApk对象WeakReferenceref;if((flags}else{ref=mResourcePackages.get(packageName);}{...returnpackageInfo;getPackageManager().getApplicationInfo(packageName,getPackageInfo(ai,compatInfo,flags);}returnnull;}publicfinalLoadedApkgetPackageInfo(ApplicationInfoai,CompatibilityInfocompatInfo,intflags){booleanincludeCode=(flagsbooleansecurityViolation=includeCode}
privateLoadedApkgetPackageInfo(ApplicationInfoaInfo,CompatibilityInfocompatInfo,ClassLoaderbaseLoader,booleansecurityViolation,booleanincludeCode){//再次从对应的成员变量中查找LoadedApk实例synchronized(mPackages){WeakReferenceref;if(includeCode){null;if(packageInfo==null||(packageInfo.mResources!=nullWeakReference(packageInfo));}else{
LoadedAp
}}PackageM
r
.
//保存Lo
SetFloatField(clazz,offsets.xdpi,info.xdpi);env->SetFloatField(clazz,offsets.ydpi,info.ydpi);}
Display的初始化过程很简单,就是通过SurfaceComposerClient请求SurfaceFlinger得到显示屏的基本信息。
frameworks/native/libs/gui/SurfaceComposerClient.cpp
status_tSurfaceComposerClient::getDisplayInfo(
DisplayIDdpy,DisplayInfo*info){if(uint32_t(dpy)>=NUM_DISPLAY_MAX)returnBAD_VALUE;volatilesurface_flinger_cblk_tconst*cblk=get_cblk();volatiledisplay_cblk_tconst*dcblk=cblk->displays+dpy;info->w=dcblk->w;info->h=dcblk->h;info->orientation=dcblk->orientation;info->xdpi=dcblk->xdpi;info->ydpi=dcblk->ydpi;info->fps=dcblk->fps;info->density=dcblk->density;returngetPixelFormatInfo(dcblk->format,}
我们知道在SurfaceFlinger启动过程中,创立了一块匿名共享内存来保存显示屏的基本信息,这里就是通过访问这块匿名共享内存来读取显示屏信息。到此一个Activity所需要的窗口对象就创立完成了,在应用程序窗口的创立过程中一共创立了以下几个对象:
info.ydp}}
Activity视图对象的创立过程
在Activity的attach函数中完成应用程序窗口的创立后,通过Instrumentation回调Activity的OnCreate函数来为当前Activity加载布局文件,进一步创立视图对象。frameworks/base/core/java/android/app/Instrumentation.java
publicvoidcallActivityOnCreate(Activityactivity,Bundleicicle){...activity.performCreate(icicle);...}
frameworks/base/core/java/android/app/Activity.java
finalvoidperformCreate(Bundleicicle){onCreate(icicle);mVisibleFromClient=!mWindow.getWindowStyle().getBoolean(
我们知道在应用程序开发中,需要重写Activity的OnCreate函数:Packages/apps/xxx/src/com/xxx/xxxActivity.java
publicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main_activity);
...}
在OnCreate函数中通过setContentView来设置Activity的布局文件,就是生成该Activity的所有视图对象。
frameworks/base/core/java/android/app/Activity.java
publicvoidsetContentView(Viewview,ViewGroup.LayoutParamsparams){getWindow().setContentView(view,params);//初始化动作条initActionBar();}
getWindow()函数得到前面创立的窗口对象PhoneWindow,通过PhoneWindow来设置Activity的视图。
c
frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindow.java
publicvoidsetContentView(intlayoutResID){//假使窗口顶级视图对象为空,则创立窗口视图对象if(mContentParent==null){installDecor();}else{//否则只是移除该视图对象中的其他视图Callbackcb=getCallback();if(cb!=nullmDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);mDecor.setIsRootNamespace(true);if
(!mInvalidatePanelMenuPostedmDecor.makeOptionalFitsSystemWindows();//应用程序窗口标题栏mTitleView=
(TextView)findViewById(ernal.R.id.title);if(mTitleView!=null){...}
else{//应用程序窗口动作条mActionBar=(ActionBarView)
findViewById(ernal.R.id.action_bar);if(mActionBar!=null){
...通过函数generateDecor()来创立一个DecorView对象
m
}
protectedDecorViewgenerateDecor(){returnnewDecorView(getContext(),-1);}
接着通过generateLayout(mDecor)来创立视图对象容器mContentParent
protectedViewGroupgenerateLayout(DecorViewdecor){//通过读取属性配置文件设置窗口风格if
(a.getBoolean(ernal.R.styleable.Window_windowActionBarOverlay,false)){requestFeature(FEATURE_ACTION_BAR_OVERLAY);}...//通过读取属性配置文件设置窗口标志if
(a.getBoolean(ernal.R.styleable.Window_windowFullscreen,false)){setFlags(FLAG_FULLSCREEN,FLAG_FULLSCREEN}...WindowManager.LayoutParamsparams=getAttributes();...mDecor.startChanging();//根据窗口主题风格选择不同的布局文件layoutResource...//加载布局文件①Viewin=mLayoutInflater.inflate(layoutResource,null);//添加到DecorView中②decor.addView(in,new
ViewGroup.LayoutParams(MATCH_PARENT,MATCH_PARENT));//从窗口视图中找出窗口内容视图对象③ViewGroupcontentParent=(ViewGroup)findViewById(ID_ANDROID_CONTENT);...
mDecor.finishChanging();
returncontentParent;}
到此Activity的所有视图对象都已经创立完毕,DecorView是Activity的顶级视图,由窗口PhoneWindow对象持有,在DecorView视图对象中添加了一个ViewGroup容器组件contentParent,所有用户定义视图组件将被添加到该容器中。handleResumeActivity
performLaunchActivity函数完成了两件事:
1)Activity窗口对象的创立,通过attach函数来完成;2)Activity视图对象的创立,通过setContentView函数来完成;这些准备工作完成后,就可以显示该Activity了,应用程序进程通过调用handleResumeActivity函数来启动Activity的显示过程。frameworks/base/core/java/android/app/ActivityThread.java
finalvoidhandleResumeActivity(IBindertoken,booleanclearHide,booleanisForward){unscheduleGcIdler();ActivityClientRecordr;//获取为窗口创立的视图
try{
DecorView对象Viewdecor=r.window.getDecorView();d
②WindowManager.LayoutParamsl=r.window.getAttributes();//将视图对象保存到Activity的成员变量mDecor中a.mDecor=decor;{l.idleScreenAvailable=false;器中③wm.addView(decor,l);r;Looper.myQueue().addIdleHandler(newIdler());
我们知道,在前面的performLaunchActivity函数中完成Activity的创立后,会将当前当前创立的Activity在应用程序进程端的描述符ActivityClientRecord以键值对的形式保存到ActivityThread的成员变量mActivities中:mActivities.put(r.token,r),r.token就是Activity的身份证,即是IApplicationToken.Proxy代理对象,也用于与AMS通信。上面的函数首先通过performResumeActivity从mActivities变量中取出Activity的应用程序端描述符ActivityClientRecord,然后取出前面为Activity创立的视图对象DecorView和窗口管理器WindowManager,最终将视图对象添加到窗口管理器中。
}}}l
我们知道Activity引用的其实是轻量级的窗口管理器LocalWindowManagerframeworks/base/core/java/android/view/Window.java
publicfinalvoidaddView(Viewview,ViewGroup.LayoutParamsparams){if(decor!=null){{//根据窗口类型设置不同的标题…if(mAppName!=null){mContainer.mAppToken;}if((curTitle==null||curTitle.length()==0)}}if(wp.packageName==null){wp.packageName=mContext.getPackageName();}if(mHardwareAccelerated){
WindowMa
t
wp.flags
LocalWindowManager的addView函数对不同类型窗口的布局参数进行相应的设置,譬如布局参数中的token设置,假使是应用程序窗口,则设置token为W本地Binder对象。假使不是应用程序窗口,同时当前窗口没有父窗口,则设置token为当前窗口的
IApplicationToken.Proxy代理对象,否则设置为父窗口的IApplicationToken.Proxy代理对象。最终视图组件的添加工作交给其父类来完成。LocalWindowManager继承于CompatModeWrapper,是WindowManagerImpl的内部类。
frameworks/base/core/java/android/view/WindowManagerImpl.java
publicvoidaddView(Viewview,android.view.ViewGroup.LayoutParamsparams){mWindowManager.addView(view,params,mCompatibilityInfo);}
前面我们介绍了,每一个Activity拥有一个轻量级窗口管理器,通过轻量级窗口管理器LocalWindowManager来访问重量级窗口管理器WindowManagerImpl,因此视图组件的添加过程又转交给了WindowManagerImpl来实现。
publicvoidaddView(Viewview,ViewGroup.LayoutParamsparams,CompatibilityInfoHoldercih){addView(view,params,cih,false);}
该函数又调用WindowManagerImpl的另一个重载函数来添加视图组件
privatevoidaddView(Viewview,ViewGroup.LayoutParamsparams,null;synchronized(this){...//从mViews中查找当前添加的Viewintindex=findViewLocked(view,false);//假使已经存在,直接返回if(index>=0){...return;}intcount=mViews!=null?mViews.length:0;for(inti=0;imAccessibilityInteractionConnectionManager=new
AccessibilityInteractionConnectionManager();mAccessibilityManager.addAccessibilityStateChangeListener(ViewConfiguration.get(context);mDensity=
context.getResources().getDisplayMetrics().densityDpi;mFallbackEventHandler=
PolicyManager.makeNewFallbackEventHandler(context);mProfileRendering=Boolean.parseBoolean(SystemProperties.get(PROPERTY_PROFILE_RENDERING,\④mChoreographer=Choreographer.getInstance();PowerManagerpowerManager=(PowerManager)context.getSystemService(Context.POWER_SERVICE);mAttachInfo.mScreenOn=powerManager.isScreenOn();loadSystemProperties();}
m
在ViewRootImpl的构造函数中初始化了一些成员变量,ViewRootImpl创立了以下几个主要对象:
1)通过getWindowSession(context.getMainLooper())得到IWindowSession的代理对象,该对象用于和WMS通信。
2)创立了一个W本地Binder对象,用于WMS通知应用程序进程。3)采用单例模式创立了一个Choreographer对象,用于统一调度窗口绘图。4)创立ViewRootHandler对象,用于处理当前视图消息。5)构造一个AttachInfo对象;
6)创立Surface对象,用于绘制当前视图,当然该Surface对象的真正创立是由WMS来完成的,只不过是WMS传递给应用程序进程的。
privatefinalSurfacemSurface=newSurface();finalViewRootHandlermHandler=newViewRootHandler();
IWindowSession代理获取过程
frameworks/base/core/java/android/view/ViewRootImpl.java
publicstaticIWindowSessiongetWindowSession(LoopermainLooper){synchronized(mStaticInit){if(!mInitialized){IWindowManagerwindowManager=Display.getWindowManager();//得到IWindowSession代理对象sWindowSession=windowManager.openSession(imm.getClient(),imm.getInputContext());(RemoteExceptione){}}returnsWindowSession;}}
以上函数通过WMS的openSession函数创立应用程序与WMS之间的连接通道,即获取IWindowSession代理对象,并将该代理对象保存到ViewRootImpl的静态成员变量sWindowSession中
staticIWindowSessionsWindowSession;
因此在应用程序进程中有且只有一个IWindowSession代理对象。
frameworks/base/services/java/com/android/server/wm/WindowManagerService.java
publicIWindowSessionopenSession(IInputMethodClientclient,IInputContextinputContext){if(client==null)thrownewIllegalArgumentException(\if(inputContext==null)thrownewIllegalArgumentException(\Sessionsession=newSession(this,client,inputContext);returnsession;}
t
在WMS服务端构造了一个Session实例对象。
AttachInfo构造过程
frameworks/base/core/java/android/view/View.java
AttachInfo(IWindowSessionsession,IWindowwindow,ViewRootImplviewRootImpl,Handlerhandler,CallbackseffectPlayer){mSession=session;//IWindowSession代理对象,用于与WMS通信mWindow=window;//W对象mWindowToken=window.asBinder();//W本地Binder对象mViewRootImpl=viewRootImpl;//ViewRootImpl实例mHandler=handler;//ViewRootHandler对象mRootCallbacks=effectPlayer;//ViewRootImpl实例}
Choreographer机制
在Android4.1之后增加了Choreographer机制,用于同Vsync机制协同,实现统一调度界面绘图.
Choreographer构造过程
frameworks/base/core/java/android/view/Choreographer.java
publicstaticChoreographergetInstance(){returnsThreadInstance.get();}
privatestaticfinalThreadLocalsThreadInstance=IllegalStateException(\
为调用线程创立一个Choreographer实例,调用线程必需具备消息循环功能,由于ViewRootImpl对象的构造是在应用程序进程的UI主线程中执行的,因此创立的Choreographer对象将使用UI线程消息队列。
privateChoreographer(Looperlooper){mLooper=looper;//创立消
息处理HandlermHandler=newFrameHandler(looper);//假使系统使用了Vsync机制,则注册一个FrameDisplayEventReceiver接收器mDisplayEventReceiver=USE_VSYNC?newFrameDisplayEventReceiver(looper):null;mLastFrameTimeNanos=Long.MIN_VALUE;//屏幕刷新周期mFrameIntervalNanos=(long)(1000000000/newDisplay(Display.DEFAULT_DISPLAY,
newThre}
null).getRefreshRate());//创立回调数组mCallbackQueues=new
CallbackQueue[CALLBACK_LAST+1];//初始化数组for(inti=0;i当VSYNC信号到达时,ChoreographerdoFrame()函数被调用
voiddoFrame(longframeTimeNanos,intframe){finallongstartNanos;synchronized(mLock){if(!mFrameScheduled){花费的时间finallongjitterNanos=startNanos-frameTimeNanos;//假使线程处理该消息的时间超过了屏幕刷新周期SKIPPED_FRAME_WARNING_LIMIT){Log.i(TAG,
if(jitt
\+
startNanos-lastFrameOffset;}//假使frameTimeNanos小于一个屏幕刷新周期,则重新请求VSync信号if(frameTimeNanosreceiver=reinterpret_cast(receiverPtr);//通过NativeDisplayEventReceiver请求VSyncstatus_tstatus=receiver->scheduleVsync();if(status){String8message;message.appendFormat(\nextvertical
syncpulse.status=%d\
jniThrowRuntimeException(env,message.string());}}status_tNativeDisplayEventReceiver::scheduleVsync(){if(!mWaitingForVsync){ALOGV(\%p~Schedulingvsync.\this);//Drainallpendingevents.nsecs_tvsyncTimestuint32_tvsyncCount;readLastVsyncMessage(status_tstatus=mReceiver.requestNextVsync();if(status){ALOGW(\nextvsync,status=%d\returnstatus;}mWaitingForVsync=true;}returnOK;}
VSync请求过程又转交给了DisplayEventReceiverframeworks/native/libs/gui/DisplayEventReceiver.cpp
status_tDisplayEventReceiver::requestNextVsync(){if(mEventConnection!=NULL)
{mEventConnection->requestNextVsync();returnNO_ERROR;}returnNO_INIT;}
这里又通过IDisplayEventConnection接口来请求Vsync信号,IDisplayEventConnection实现了Binder通信框架,可以跨进程调用,由于Vsync信号请求进程和Vsync产生进程有可能不在同一个进程空间,因此这里就借助IDisplayEventConnection接口来实现。下面通过图来梳理Vsync请求的调用流程:
视图View添加过程
窗口管理器WindowManagerImpl为当前添加的窗口创立好各种对象后,调用ViewRootImpl的setView函数向WMS服务添加一个窗口对象。
GetIntField(session,sso.client);spsurface;if(jname==NULL){surface=client->createSurface(dpy,w,h,format,flags);}else{constjchar*str=env->GetStringCritical(jname,0);0){jniThrowException(env,OutOfResourcesException,NULL);return;}setSurfaceControl(env,clazz,surface);}
到此才算真正创立了一个可用于绘图的Surface,从上面的分析我们可以看出,在WMS服务进程端,其实创立了两个Java层的Surface对象,第一个Surface使用了无参构造函数,
...
0,w,h,
mWin.mHa
jobject
constSt
仅仅构造一个Surface对象而已,而其次个Surface却使用了有参构造函数,参数指定了图象宽高等信息,这个Java层Surface对象还会在native层请求SurfaceFlinger创立一个真正能用于绘制图象的native层Surface。最终通过浅拷贝的方式将其次个Surface复制到第一个Surface中,最终通过writeToParcel方式写回到应用程序进程。
到目前为止,应用程序和WMS一共创立了3个Java层Surface对象,如上图所示,而真正能用于绘图的Surface只有3号,那么3号Surface与2号Surface之间是什么关系呢?outSurface.copyFrom(surface)
frameworks/base/core/jni/android_view_Surface.cpp
staticvoidSurface_copyFrom(JNIEnv*env,jobjectclazz,jobjectother){if(clazz==other)return;if(other==NULL){SurfaceControl对象constsp//假使它们引用的不是同一个SurfaceControl对象if(!SurfaceControl::isSameSurface(surface,rhs)){setSurfaceControl(env,clazz,rhs);}}
2号Surface引用到了3号Surface的SurfaceControl对象后,通过writeToParcel()函数写会到应用程序进程。frameworks/base/core/jni/android_view_Surface.cpp
doThrowN
staticvoidSurface_writeToParcel(JNIEnv*env,jobjectclazz,jobjectargParcel,jintflags){Parcel*parcel=(Parcel*)env->GetIntField(argParcel,no.native_parcel);if(parcel==NULL){doThrowNPE(env);return;}constspif(control!=NULL){{Surface::writeToParcel(surface,parcel);NULL);setSurface(env,clazz,NULL);}}
由于2号Surface引用的SurfaceControl对象不为空,因此这里就将SurfaceControl对象写会给应用程序进程frameworks/native/libs/gui/Surface.cpp
SurfaceC
}else{
status_tSurfaceControl::writeSurfaceToParcel(const
spuint32_tidentity=0;if(SurfaceControl::isValid(control)){sur=control->mSurface;identity=control->mIdentity;}parcel->writeStrongBinder(sur!=0?sur->asBinder():NULL);parcel->writeStrongBinder(NULL);//NULLISurfaceTextureinthiscase.parcel->writeInt32(identity);returnNO_ERROR;}
写入Parcel包裹的对象顺序如下:
应用程序进程中的1号Surface通过readFromParcel()函数读取从WMS服务进程写回的Binder对象。
frameworks/base/core/jni/android_view_Surface.cpp
staticvoidSurface_readFromParcel(JNIEnv*env,jobject
clazz,jobjectargParcel){Parcel*parcel=
(Parcel*)env->GetIntField(argParcel,no.native_parcel);if
(parcel==NULL){doThrowNPE(env);return;}
spsur(Surface::readFromParcel(*parcel));setSurface(env,clazz,sur);}
frameworks/native/libs/gui/Surface.cpp
spSurface::readFromParcel(constParcelspbinder(data.readStrongBinder());spsurface=sCachedSurfaces.valueFor(binder).promote();if(surface==0){surface=newSurface(data,binder);sCachedSurfaces.add(binder,surface);}else{//TheSurfacewasfoundinthecache,butwestillshouldclearany//remainingdatafromtheparcel.data.readStrongBinder();//ISurfaceTexturesurface;}
应用程序进程中的1号Surface按相反顺序读取WMS服务端返回过来的Binder对象等数据,并构造一个native层的Surface对象。
data.rea
Surface::Surface(constParcelsp
st_binder(parcel.readStrongBinder());spst;if(st_binder!=NULL){st=
interface_cast(st_binder);}elseif(mSurface!=NULL){st=mSurface->getSurfaceTexture();}mIdentity=parcel.readInt32();init(st);}
每个Activity可以有一个或多个Surface,默认状况下一个Activity只有一个Surface,当Activity中使用SurfaceView时,就存在多个Surface。Activity默认surface是在relayoutWindow过程中由WMS服务创立的,然后回传给应用程序进程,我们知道一个Surface其实就是应用程序端的本地窗口,关于Surface的初始化过程这里就不在介绍。performLayout
frameworks/base/core/java/android/view/ViewRootImpl.java
privatevoidperformLayout(){mLayoutRequested=false;mScrollMayChange=true;finalViewhost=mView;if(DEBUG_ORIENTATION||DEBUG_LAYOUT){Log.v(TAG,\host.getMeasuredHeight());}finally{Trace.traceEnd(Trace.TRACE_TAG_VIEW);}}
performDraw
frameworks/base/core/java/android/view/ViewRootImpl.java
privatevoidperformDraw(){if(!mAttachInfo.mScreenOn}finalboolean
fullRedrawNeeded=mFullRedrawNeeded;mFullRedrawNeeded=false;mIsDrawing=true;Trace.traceBegin(Trace.TRACE_TAG_VIEW,\try{draw(fullRedrawNeeded);}finally{mIsDrawing=false;Trace.traceEnd(Trace.TRACE_TAG_VIEW);}...}
privatevoiddraw(booleanfullRedrawNeeded){Surfacesurface=mSurface;if(surface==null||!surface.isValid()){return;}...if(!dirty.isEmpty()||mIsAnimating){
host.get
//使用硬件渲染if
(attachInfo.mHardwareRenderer!=nullresizeAlpha;mCurrentDirty.set(dirty);this,animating?null:mCurrentDirty)){mPreviousDirty.set(0,0,mWidth,mHeight);}//使用软件渲染}elseif(!drawSoftware(surface,attachInfo,yoff,scalingRequired,dirty)){return;}}...}
m
mCurrent
窗口添加过程
frameworks/base/services/java/com/android/server/wm/Session.java
publicintadd(IWindowwindow,intseq,WindowManager.LayoutParamsattrs,intviewVisibility,RectoutContentInsets,InputChanneloutInputChannel){returnmService.addWindow(this,window,seq,attrs,viewVisibility,outContentInsets,outInputChannel);}
frameworks/base/services/java/com/android/server/wm/WindowManagerService.java
publicintaddWindow(Sessionsession,IWindowclient,intseq,=mPolicy.checkAddPermission(attrs);if(res!=WindowManagerImpl.ADD_OKAY){returnres;}booleanreportNewConfig=false;WindowStateattachedWindow=null;WindowStatewin=null;longorigId;synchronized(mWindowMap){if(mDisplay==null){{Slog.w(TAG,\added\returnWindowManagerImpl.ADD_DUPLICATE_ADD;}//假使添加的是应用程序窗口if(attrs.type>=FIRST_SUB_WINDOWif(attachedWindow==null){Slog.w(TAG,\window:\+attrs.token+\returnWindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;}thatisasub-window:\+attrs.token+\returnWindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;}mTokenMap.get(attrs.token);if(token==null){FIRST_APPLICATION_WINDOW...}//输入法窗口elseif(attrs.type==TYPE_INPUT_METHOD){...}//墙纸窗口=newWindowState(this,session,client,token,{Stringname=win.makeInputChannelName();InputChannel.openInputChannelPair(name);
WindowMa
i
}
...
elseifattachedI
win.setInputChannel(inputChannels[0]);
inputChannels[1].transferTo(outInputChannel);
mInputManager.registerInputChannel(win.mInputChannel,win.mInputWindowHandle);}...//以键值对形式保存到mTokenMap表中if(addToken){③mTokenMap.put(attrs.token,token);}④win.attach();//以键值对形式保存到mWindowMap表中⑤mWindowMap.put(client.asBinder(),win);...}...returnres;}
我们知道当应用程序进程添加一个DecorView到窗口管理器时,会为当前添加的窗口创立ViewRootImpl对
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 收银对账操作流程
- 艾灸养生疗法安全指南
- 家政员心理健康辅导服务方案
- 安全风险分级管控工作指引
- 花卉采后保鲜贮藏技术规程
- 环境突发事故应急监测方案
- 化肥减量增效施用技术操作指引
- 春季玉米密植高产生产方案
- 新客户首次到店体验指南
- 牵引理疗注意事项规范
- 2026贵州遵义市政务服务管理局下属事业单位招聘编外人员2人考试模拟试题及答案解析
- 江苏省2026年中职职教高考文化统考数学试卷及答案
- 校园创意设计
- 2026年北京市东城区高三二模生物试卷(含答案)
- 2026滁州市轨道交通运营有限公司第一批次校园招聘21人备考题库及完整答案详解一套
- 长期照护师职业技能鉴定考试复习题库(附答案)
- 嘉定区家委会工作制度
- 医疗机构医院医用高压氧治疗技术管理规范(2022年版)
- 2025年贵州省高考化学试卷真题(含答案)
- 国开大政府经济学自测题1-14章
- 在《人民报》创刊纪念会上的演说教学高中语文必修下册课件
评论
0/150
提交评论