96SEO 2026-02-20 03:14 8
在《浅析Android中View的测量布局流程》中我们对VSYNC信号到达App进程之后开启的View布局过程进行了分析经过对整个App界面的View树进行遍历完成了测量和布局确定了View的大小以及在屏幕中所处的位置。

但是如果想让用户在屏幕上看到View的内容还需要根据View的绘制生成图形数据并交由硬件进行屏幕刷新。
View的绘制主要负责将业务层的各种API调用转换为指令然后交给渲染引擎进行处理最终生成能够被硬件直接处理的数据。
这个过程主要分为渲染数据的生产以及消费一般来说渲染数据的生产者是各个App进程而消费者则是SurfaceFlinger进程这里会涉及到渲染数据的跨进程传输问题。
下面将会对渲染数据的跨进程传输的实现进行分析。
Surface作为数据载体负责打通App进程与SurfaceFlinger进程之间的数据交互同时Surface是属于App进程内的资源因此先从App进程这个生产者出发基于Surface的创建流程及其使用对渲染数据的传递机制进行分析。
在《浅析Android中View的测量布局流程》中有分析到当测量数据发生变化时需要对窗体大小进行更新因为测量数据的变化导致视图展示区域随之发生变化。
根据分析测量布局流程的相关源码实现可知一个ViewRootImpl对象被创建时都会创建一个Surface对象以及SurfaceControl对象但是Surface对象并不是立即可用于绘制渲染的而只是一个壳子其真正的实现是在native层。
而在测量之后宽高如果发生变化则需要对窗口大小进行更新此时会对Surface以及SurfaceControl对象进行处理即更新native层的Surface以及SurfaceControl对象之后Surface对象将进入可用状态。
首先App进程为每一个Activity创建了一个Window而每一个Window会对应一个ViewRootImpl每一个ViewRootImpl持有一个Surface以及SurfaceControl对象。
然后SystemServer进程会对应地为App进程的每一个Window创建一个Window相对应地也会为每一个Window创建一个SurfaceControl对象。
下面我们看下SystemServer进程中的SurfaceControl的创建过程。
ThreadedRenderer.DrawCallbacks,
ViewGroup.LayoutParams.WRAP_CONTENT
ViewGroup.LayoutParams.WRAP_CONTENT
relayoutWindow(WindowManager.LayoutParams
mWindowSession是IWindowSession类型的对象即Binder代理对象对应实现是SystemServer进程中的Session类的实例每个进程的IWindowSession对应SystemServer进程中一个Session实例relayoutResult
mWindowSession.relayout(mWindow,
WindowManagerGlobal.RELAYOUT_INSETS_PENDING
mSurfaceControl实例可用之后根据mSurfaceControl的Surface信息对mSurface进行更新if
{mSurface.copyFrom(mSurfaceControl);}
{updateBlastSurfaceIfNeeded();}//
}relayoutWindow方法会通过Binder请求到SystemServer进程对之前SystemServer进程中创建的window实例进行更新。
mWindowSession.relayout会调用到WindowManagerService中的相关逻辑经过relayout方法调用了WindowManagerService#createSurfaceControl方法完成SystemServer进程中SurfaceControl对象的创建。
从SystemServer进程返回之后通过getSurfaceControl方法将新创建的SurfaceControl对象的属性拷贝回App进程的SurfaceControl对象即ViewRootImpl#mSurfaceControl中。
Session代表一个活跃的客户端session。
SystemServer进程中会为每个进程维护一个Session对象用于window相关的Binder通信。
*/
com.android.server.wm.WindowManagerService
WindowManagerPolicy.WindowManagerFuncs
获取窗体状态描述每一个Window通常对应一个Activity都对应一个WindowState。
final
获取WindowStateAnimator用于创建SurfaceControlWindowStateAnimator
只有view可见或者相关联的appToken没有隐藏时才应该relayout。
final
win.mActivityRecord.isClientVisible());//
创建SurfaceControl并将其拷贝到outSurfaceControloutSurfaceControlresult
createSurfaceControl(outSurfaceControl,
createSurfaceControl(SurfaceControl
RELAYOUT_RES_SURFACE_CHANGED;}WindowSurfaceController
通过WindowStateAnimator对象创建WindowSurfaceController对象surfaceController
winAnimator.createSurfaceLocked();}
通过WindowSurfaceController将SurfaceController拷贝到outSurfaceControl中outSurfaceControl对应App进程中的ViewRootImpl的mSurfaceControl变量surfaceController.getSurfaceControl(outSurfaceControl);
...outSurfaceControl.release();}return
为单个WindowState跟踪动画和surface的操作.**///
com.android.server.wm.WindowStateAnimator
创建WindowSurfaceControllerWindowSurfaceController
WindowSurfaceController(attrs.getTitle().toString(),
com.android.server.wm.WindowSurfaceController
{WindowSurfaceController(String
win.makeSurface().setParent(win.getSurfaceControl()).setName(name).setFormat(format).setFlags(flags).setMetadata(METADATA_WINDOW_TYPE,
windowType).setMetadata(METADATA_OWNER_UID,
mWindowSession.mUid).setMetadata(METADATA_OWNER_PID,
mWindowSession.mPid).setCallsite(WindowSurfaceController);//
}可以看出WindowSurfaceController是SurfaceControl的包装类通过持有SurfaceControl对象来对Surface进行操作WindowSurfaceController以及SurfaceControl都是在SystemServer进程创建的。
接下来继续跟着SurfaceControl的构造函数看下SurfaceControl的创建具体做了哪些事情。
持有一个由系统合成器管理的Surface对象。
这个SurfaceControl对象由buffer以及如何显示buffer的信息组成。
*
通过构造的Surface对象可以提交数据到buffer用于合成上屏。
*/
...assignNativeObject(nativeObject,
OutOfResourcesException;private
sRegistry.registerNativeAllocation(this,
记录native层Surface对象的句柄值mNativeObject
null;}setUnreleasedWarningCallSite(callsite);addToRegistry();}
}从源码可以看出Java层的SurfaceControl对象其实是一个壳其内部的主要实现是在native层的SurfaceControl对象中的通过持有native层的SurfaceControl对象的句柄值对其进行调用。
因此SurfaceControl的关键实现在nativeCreate这个native方法中。
frameworks/base/core/jni/android_view_SurfaceControl.cpp
获取SurfaceComposerClient对象SurfaceComposerClient对象负责与SurfaceFlinger进程进行交互spSurfaceComposerClient
android_view_SurfaceSession_getClient(env,
SurfaceComposerClient::getDefault();}SurfaceControl
reinterpret_castSurfaceControl*(parentObject);spSurfaceControl
client-createSurfaceChecked(String8(name.c_str()),
java/lang/IllegalArgumentException,
statusToString(err).c_str());return
reinterpret_castjlong(surface.get());
}从源码中得知通过SurfaceComposerClient调用createSurfaceChecked方法进行native层的SurfaceControl的创建内部通过成员变量mClient跨进程调用到SurfaceFlinger进程mClient的远程实现是SurfaceFlinger进程的Client类。
frameworks/native/libs/gui/SurfaceComposerClient.cpp
SurfaceComposerClient::createSurfaceChecked(const
请求SurfaceFlinger进程创建一个SurfaceControlbinder::Status
mClient-createSurface(std::string(name.c_str()),
statusTFromBinderStatus(status);//
根据CreateSurfaceResult构造SurfaceControl对象并将其返回//
result.handle是一个Binder对象封装了SurfaceFlinger进程的Layer以及SurfaceFlinger*outSurface
frameworks/native/libs/gui/SurfaceControl.cpp
SurfaceControl::SurfaceControl(const
mClient(client),mHandle(handle),mLayerId(layerId),mName(name),mTransformHint(transform),mWidth(w),mHeight(h),mFormat(format),mCreateFlags(flags)
{}SurfaceFlinger进程调用Client::createSurface创建Surface对象并根据方法的返回结果构造了SystemServer进程的SurfaceControl对象并将其返回最终拷贝回App进程的SurfaceControl对象即ViewRootImpl#mSurfaceControl。
但是到这里其实并没有发现跨进程传输数据相关的代码实现因此只能继续看下SurfaceFlinger进程的Client::createSurface方法具体做了什么事情。
frameworks/native/services/surfaceflinger/Client.cpp
std::move(metadata));args.parentHandle
为App进程的SurfaceControl创建Layerconst
binderStatusFromStatusT(status);
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
SurfaceFlinger::createLayer(LayerCreationArgs
ISurfaceComposerClient::eFXSurfaceMask)
ISurfaceComposerClient::eFXSurfaceBufferQueue:case
ISurfaceComposerClient::eFXSurfaceContainer:case
ISurfaceComposerClient::eFXSurfaceBufferState:args.flags
ISurfaceComposerClient::eNoColorFill;[[fallthrough]];case
ISurfaceComposerClient::eFXSurfaceEffect:
layer-getPendingBufferCounter();if
layer-getPendingBufferCounterName();mBufferCountTracker.add(outResult.handle-localBinder(),
LayerHandle::getLayer(args.parentHandle.promote());uint32_t
outTransformHint);outResult.layerId
layer-sequence;outResult.layerName
String16(layer-getDebugName());return
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
SurfaceFlinger::createBufferStateLayer(LayerCreationArgs
getFactory().createBufferStateLayer(args);*handle
frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
DefaultFactory::createBufferStateLayer(const
frameworks/native/services/surfaceflinger/Layer.cpp
surfaceflinger::LayerCreationArgs
sequence(args.sequence),mFlinger(spSurfaceFlinger::fromExisting(args.flinger)),mName(base::StringPrintf(%s#%d,
sequence)),mClientRef(args.client),mWindowType(static_castWindowInfo::Type(args.metadata.getInt32(gui::METADATA_WINDOW_TYPE,
0))),mLayerCreationFlags(args.flags),mLegacyLayerFE(args.flinger-getFactory().createLayerFE(mName,
}SurfaceFlinger进程中调用了SurfaceFlinger::createBufferStateLayer方法创建了Layer对象因此SystemServer进程中的SurfaceControl对象对应SurfaceFlinger进程的Layer对象。
上面提到经过App进程到SystemServer进程再到SurfaceFlinger进程最终完成了一系列window相关的对象创建。
最终依次返回并将相关信息跨进程拷贝回App进程。
之后因为App进程的mSurfaceControl处于有效状态此时将会App进程的mSurface进行更新操作。
ThreadedRenderer.DrawCallbacks,
mWindowSession.addToDisplayAsUser(mWindow,
mInsetsController.getRequestedVisibilities(),
是否开启BLAST取决于SystemServer进程返回的resif
WindowManagerGlobal.ADD_FLAG_USE_BLAST)
relayoutWindow(WindowManager.LayoutParams
mWindowSession.relayout(mWindow,
WindowManagerGlobal.RELAYOUT_INSETS_PENDING
mSurfaceControl实例可用之后根据mSurfaceControl的Surface信息对mSurface进行更新if
{mSurface.copyFrom(mSurfaceControl);}
{updateBlastSurfaceIfNeeded();}//
}在更新mSurface之前会判断是否使用BLAST而是否使用BLAST是在addView的时候由SystemServer进程决定的根据源码可知Android
S开始默认开启BLAST因此最后调用了updateBlastSurfaceIfNeeded方法其内部会调用Surface#transferFrom方法进而拷贝mNativeObject的值。
outActiveControls,outAttachedFrame,
com.android.server.wm.WindowManagerService
WindowManagerPolicy.WindowManagerFuncs
atm,DisplayWindowSettingsProvider
displayWindowSettingsProvider,SupplierSurfaceControl.Transaction
transactionFactory,FunctionSurfaceSession,
Settings.Global.getInt(resolver,
Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_VR,
requestedVisibleTypes,InputChannel
outInsetsState,InsetsSourceControl.Array
mPolicy.checkAddPermission(attrs.type,
WindowManagerGlobal.ADD_FLAG_USE_BLAST;}//
...}Binder.restoreCallingIdentity(origId);return
ThreadedRenderer.DrawCallbacks,
如果对应的native层的SurfaceControl对象是同一个则直接更新即可不需要重新创建BLASTBufferQueueif
mBlastBufferQueue.isSameSurfaceControl(mSurfaceControl))
{mBlastBufferQueue.update(mSurfaceControl,
mWindowAttributes.format);return;}//
如果更新了SurfaceControl那么销毁并重建BBQBLASTBufferQueue来重置BufferQueue及BLASTBufferQueue的状态.if
{mBlastBufferQueue.destroy();}mBlastBufferQueue
mWindowAttributes.format);mBlastBufferQueue.setTransactionHangCallback(sTransactionHangCallback);Surface
mBlastBufferQueue.createSurface();//
recreated.mSurface.transferFrom(blastSurface);}//
S开始由App进程创建管理BufferQueue即ViewRootImpl#mBlastBufferQueue。
那BLASTBufferQueue是在什么时候创建的呢查看源码发现其实就是在ViewRootImpl#updateBlastSurfaceIfNeeded方法中创建的。
下面看下BLASTBufferQueue的创建过程。
根据上面的分析得出App进程在创建完SurfaceControl之后会继续创建BLASTBufferQueue并且在创建BLASTBufferQueue之前并没有发现和图像数据跨进程传输相关的代码实现所以不妨假设下BLASTBufferQueue的创建其实就是为跨进程传输图像数据做准备。
android.graphics.BLASTBufferQueue
updateDestinationFrame);}private
updateDestinationFrame);private
}从BLASTBufferQueue的构造函数可以看到和SurfaceControl以及Surface类似都是通过JNI调用到native层去创建对应的对象。
因此Java层的BLASTBufferQueue对象也是native层的BLASTBufferQueue的壳因此进一步分析native层的代码。
frameworks/base/core/jni/android_graphics_BLASTBufferQueue.cpp
updateDestinationFrame);queue-incStrong((void*)nativeCreate);return
reinterpret_castjlong(queue.get());
reinterpret_castBLASTBufferQueue*(ptr);queue-update(reinterpret_castSurfaceControl*(surfaceControl),
}native层在创建了BLASTBufferQueue对象之后调用了BLASTBufferQueue::update方法。
frameworks/native/libs/gui/BLASTBufferQueue.cpp
BLASTBufferQueue::BLASTBufferQueue(const
mSurfaceControl(nullptr),mSize(1,
1),mRequestedSize(mSize),mFormat(PIXEL_FORMAT_RGBA_8888),mTransactionReadyCallback(nullptr),mSyncTransaction(nullptr),mUpdateDestinationFrame(updateDestinationFrame)
先创建BufferQueue然后初始化mProducer以及mConsumercreateBufferQueue(mProducer,
因为是在client进程因此为dequeue操作设置超时来保证dequeueBuffer时会阻塞线程。
mProducer-setDequeueTimeout(std::numeric_limitsint64_t::max());//
buffer的默认数量为2mProducer-setMaxDequeuedBufferCount(2);//
封装BufferQueueConsumermBufferItemConsumer
BLASTBufferItemConsumer(mConsumer,
GraphicBuffer::USAGE_HW_COMPOSER
GraphicBuffer::USAGE_HW_TEXTURE,
std::to_string(mProducerId);auto
std::to_string(mProducerId);mQueuedBufferTrace
std::to_string(mProducerId);mBufferItemConsumer-setName(String8(consumerName.c_str()));//
设置监听器用于当帧数据可用时消费Buffer数据mBufferItemConsumer-setFrameAvailableListener(this);ComposerServiceAIDL::getComposerService()-getMaxAcquiredBufferCount(mMaxAcquiredBuffers);mBufferItemConsumer-setMaxAcquiredBufferCount(mMaxAcquiredBuffers);mCurrentMaxAcquiredBufferCount
mMaxAcquiredBuffers;mNumAcquired
0;TransactionCompletedListener::getInstance()-addQueueStallListener([](const
BLASTBufferQueue::createBufferQueue(spIGraphicBufferProducer*
将BufferQueueCore传入BBQBufferQueueProducer这样当producer发起调用时可以异步化通过持有的BufferQueueCore将结果返回spIGraphicBufferProducer
BufferQueueConsumer(core));consumer-setAllowExtraAcquire(true);*outProducer
frameworks/native/libs/gui/BufferQueueCore.cpp
BufferQueueCore::BufferQueueCore():
mMutex(),mIsAbandoned(false),mConsumerControlledByApp(false),
consumer不是给App控制的mConsumerName(getUniqueName()),mConsumerListener(),mConsumerUsageBits(0),mConsumerIsProtected(false),mConnectedApi(NO_CONNECTED_API),mLinkedToDeath(),mConnectedProducerListener(),mBufferReleasedCbEnabled(false),mBufferAttachedCbEnabled(false),mSlots(),
元素类型为BufferItem的Vector变量mFreeSlots(),
元素类型为int的set对应没有buffer的索引位置mFreeBuffers(),
元素类型为int的list对应空闲buffer的索引位置mUnusedSlots(),
元素类型为int的list对应可以被释放的buffer的索引位置mActiveBuffers(),
元素类型为int的set对应正在使用的buffer的索引位置mDequeueCondition(),mDequeueBufferCannotBlock(false),mQueueBufferCanDrop(false),mLegacyBufferDrop(true),mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),mDefaultWidth(1),mDefaultHeight(1),mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN),mMaxBufferCount(BufferQueueDefs::NUM_BUFFER_SLOTS),mMaxAcquiredBufferCount(1),mMaxDequeuedBufferCount(1),mBufferHasBeenQueued(false),mFrameCounter(0),mTransformHint(0),mIsAllocating(false),mIsAllocatingCondition(),mAllowAllocation(true),mBufferAge(0),mGenerationNumber(0),mAsyncMode(false),mSharedBufferMode(false),mAutoRefresh(false),mSharedBufferSlot(INVALID_BUFFER_SLOT),mSharedBufferCache(Rect::INVALID_RECT,
NATIVE_WINDOW_SCALING_MODE_FREEZE,HAL_DATASPACE_UNKNOWN),mLastQueuedSlot(INVALID_BUFFER_SLOT),mUniqueId(getUniqueId()),mAutoPrerotation(false),mTransformHintInUse(0)
BufferQueueDefs::NUM_BUFFER_SLOTS;s)
}这里创建了BufferQueueCore对象并基于BufferQueueCore对象创建了BBQBufferQueueProducer以及BufferQueueConsumer分别是BufferQueueCore的生产者和消费者并被BLASTBufferQueue的mProducer和mConsumer持有mProducer的主要操作包括dequeueBuffer和queueBuffermConsumer的主要操作包括acquireBuffer和releaseBuffer。
可以看到这里主要是创建了一个BufferQueueCore对象用于管理Buffer而Buffer是通过mProducer和mConsumer使用的所以看下mProducer和mConsumer的内部实现。
通过源码可以看出mProducer和mConsumer都是通过持有BufferQueueCore来使用buffer的而mProducer和mConsumer中都提供了使用buffer的方法。
frameworks/native/libs/gui/BLASTBufferQueue.cpp
mBLASTBufferQueue(std::move(bbq))
{}BufferQueueConsumer::BufferQueueConsumer(const
:mCore(core),mSlots(core-mSlots),mConsumerName()
frameworks/native/libs/gui/BufferQueueProducer.cpp
BufferQueueProducer::BufferQueueProducer(const
:mCore(core),mSlots(core-mSlots),mConsumerName(),mStickyTransform(0),mConsumerIsSurfaceFlinger(consumerIsSurfaceFlinger),mLastQueueBufferFence(Fence::NO_FENCE),mLastQueuedTransform(0),mCallbackMutex(),mNextCallbackTicket(0),mCurrentCallbackTicket(0),mCallbackCondition(),mDequeueTimeout(-1),mDequeueWaitingForAllocation(false)
frameworks/native/libs/gui/include/gui/BufferQueueProducer.h//
dequeueBuffer获取下一个buffer的slot索引给producer使用。
slot那么就把slot索引写入参数处并返回否则返回-EBUSY。
requestBuffer返回GraphicBuffer到第N个slot。
N的时候。
但是如果dequeueBuffer返回的flags表明之前返回的buffers已经失效的话就必须再次调用requestBuffer。
queueBuffer返回一个填充过的buffer到BufferQueue。
frameworks/native/libs/gui/BufferQueueConsumer.cpp
BufferQueueConsumer::BufferQueueConsumer(const
:mCore(core),mSlots(core-mSlots),mConsumerName()
frameworks/native/libs/gui/include/gui/BufferQueueConsumer.h//
acquireBuffer尝试获取BufferQueue中的下一个pending的buffer的使用权如果没有pending的buffer就返回NO_BUFFER_AVAILABLE。
如果一个buffer被成功的获取到将会返回一个包含buffer相关的信息的BufferItem。
slot到BufferQueue中。
releaseBuffer调用时有可能还在访问buffer的内容。
fence);当完成BLASTBufferQueue的创建之后通过update方法更新持有的SurfaceControl变量将其指向新的SurfaceControl对象。
frameworks/native/libs/gui/BLASTBufferQueue.cpp
format;mBufferItemConsumer-setDefaultBufferFormat(convertBufferFormat(format));}const
!SurfaceControl::isSameSurface(mSurfaceControl,
更新持有的SurfaceControl变量mSurfaceControl
surface;SurfaceComposerClient::Transaction
layer_state_t::eEnableBackpressure,
layer_state_t::eEnableBackpressure);applyTransaction
mSurfaceControl-getTransformHint();mBufferItemConsumer-setTransformHint(mTransformHint);ui::Size
{mRequestedSize.set(newSize);mBufferItemConsumer-setDefaultBufferSize(mRequestedSize.width,
NATIVE_WINDOW_SCALING_MODE_FREEZE)
{t.setDestinationFrame(mSurfaceControl,
Rect(newSize));applyTransaction
mAppliedLastTransactiont.setApplyToken(mApplyToken).apply(false,
在创建完BLASTBufferQueue之后会通过新创建的BLASTBufferQueue对象创建一个Surface对象并用新的Surface对象更新ViewRootImpl#mSurface主要是将内部持有的native层的句柄值更新为BLASTBufferQueue对象创建的native的句柄值。
ThreadedRenderer.DrawCallbacks,
如果对应的native层的SurfaceControl对象是同一个则直接更新即可不需要重新创建BLASTBufferQueueif
mBlastBufferQueue.isSameSurfaceControl(mSurfaceControl))
{mBlastBufferQueue.update(mSurfaceControl,
mWindowAttributes.format);return;}//
如果更新了SurfaceControl那么销毁并重建BBQBLASTBufferQueue来重置BufferQueue及BLASTBufferQueue的状态.if
{mBlastBufferQueue.destroy();}mBlastBufferQueue
mWindowAttributes.format);mBlastBufferQueue.setTransactionHangCallback(sTransactionHangCallback);//
通过新创建的BLASTBufferQueue对象创建Surface对象并用新的Surface对象更新mSurfaceSurface
mBlastBufferQueue.createSurface();//
recreated.mSurface.transferFrom(blastSurface);}//
}可以看到最终还是BLASTBufferQueue调用nativeGetSurface到了native层去创建Surface对象这里Surface对象就持有了BLASTBufferQueue的mProducer这样就可以通过Surface访问BBQBufferQueueProducer然后通过BBQBufferQueueProducer访问BufferQueueCore最终实现Buffer的访问使用。
nativeGetSurface(mNativeObject,
frameworks/base/core/jni/android_graphics_BLASTBufferQueue.cpp
reinterpret_castBLASTBufferQueue*(ptr);return
android_view_Surface_createFromSurface(env,
queue-getSurface(includeSurfaceControlHandle));
frameworks/native/libs/gui/BLASTBufferQueue.cpp
BLASTBufferQueue::getSurface(bool
mSurfaceControl-getHandle();}return
frameworks/native/libs/gui/BLASTBufferQueue.cpp
frameworks/native/libs/gui/Surface.cpp
mGraphicBufferProducer(bufferProducer),mCrop(Rect::EMPTY_RECT),mBufferAge(0),mGenerationNumber(0),mSharedBufferMode(false),mAutoRefresh(false),mAutoPrerotation(false),mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),mSharedBufferHasBeenQueued(false),mQueriedSupportedTimestamps(false),mFrameTimestampsSupportsPresent(false),mEnableFrameTimestamps(false),mFrameEventHistory(std::make_uniqueProducerFrameEventHistory())
pointers.ANativeWindow::setSwapInterval
hook_setSwapInterval;ANativeWindow::dequeueBuffer
hook_dequeueBuffer;ANativeWindow::cancelBuffer
hook_cancelBuffer;ANativeWindow::queueBuffer
hook_queueBuffer;ANativeWindow::query
hook_query;ANativeWindow::perform
hook_perform;ANativeWindow::dequeueBuffer_DEPRECATED
hook_dequeueBuffer_DEPRECATED;ANativeWindow::cancelBuffer_DEPRECATED
hook_cancelBuffer_DEPRECATED;ANativeWindow::lockBuffer_DEPRECATED
hook_lockBuffer_DEPRECATED;ANativeWindow::queueBuffer_DEPRECATED
hook_queueBuffer_DEPRECATED;const_castint(ANativeWindow::minSwapInterval)
0;const_castint(ANativeWindow::maxSwapInterval)
首先当App进程的View的测量数据发生变化时会导致窗体大小发生变化此时会调用ViewRootImpl#relayoutWindow请求SystemServer进程的WindowManagerService更新窗体的大小SystemServer进程会做如下工作
SystemServer进程通过WindowManagerService创建Java层的SurfaceControl对象对应App进程中Java层的SurfaceControl对象SystemServer进程创建的Java层的SurfaceControl对象是一个壳其内部会通过JNI调用到native层创建native层的SurfaceControl对象并将native层的SurfaceControl对象的句柄值拷贝到App进程的SurfaceControl对象在native层的SurfaceControl对象创建的过程中会通过SurfaceComposerClient请求到SurfaceFlinger进程调用Client::createSurface创建Layer对象并将Layer对象的关键信息返回给
SystemServer进程并用于构造native层的SurfaceControl对象
接着当App进程的Java层的SurfaceControl对象更新了native层的SurfaceControl对象之后便会创建Java层的BLASTBufferQueue对象同样地Java层的BLASTBufferQueue对象会触发native层的BLASTBufferQueue对象的创建native层BLASTBufferQueue对象的创建会做如下工作
创建BufferQueueCore并通过BufferQueueCore创建IGraphicBufferProducerBBQBufferQueueProducer以及BufferQueueConsumer并被BLASTBufferQueue对象持有调用BufferQueueCore#update方法将BufferQueueCore持有的SurfaceControl变量指向之前创建的新SurfaceControl对象
最后当SurfaceControl和BLASTBufferQueue都创建完成之后通过BLASTBufferQueue对象创建一个native层的Surface对象持有了BLASTBufferQueue的IGraphicBufferProducer并将其赋值给App进程的ViewRootImpl#mSurface持有的句柄值最终实现通过Surface访问BBQBufferQueueProducer然后通过BBQBufferQueueProducer访问BufferQueueCore最终对Buffer进行访问使用。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback