谷歌SEO

谷歌SEO

Products

当前位置:首页 > 谷歌SEO >

如何找到免费建站推广的漫画网站?

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的创建过程。

public

ThreadedRenderer.DrawCallbacks,

{final

ViewGroup.LayoutParams.WRAP_CONTENT

frame.width()

ViewGroup.LayoutParams.WRAP_CONTENT

frame.height()

relayoutWindow(WindowManager.LayoutParams

params,

mWindowSession是IWindowSession类型的对象即Binder代理对象对应实现是SystemServer进程中的Session类的实例每个进程的IWindowSession对应SystemServer进程中一个Session实例relayoutResult

mWindowSession.relayout(mWindow,

params,

WindowManagerGlobal.RELAYOUT_INSETS_PENDING

mTmpFrames,

mSurfaceControl实例可用之后根据mSurfaceControl的Surface信息对mSurface进行更新if

{if

{mSurface.copyFrom(mSurfaceControl);}

else

{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通信。

*/

class

com.android.server.wm.WindowManagerService

public

WindowManagerPolicy.WindowManagerFuncs

{//

获取窗体状态描述每一个Window通常对应一个Activity都对应一个WindowState。

final

WindowState

获取WindowStateAnimator用于创建SurfaceControlWindowStateAnimator

winAnimator

只有view可见或者相关联的appToken没有隐藏时才应该relayout。

final

boolean

win.mActivityRecord.isClientVisible());//

...if

创建SurfaceControl并将其拷贝到outSurfaceControloutSurfaceControlresult

createSurfaceControl(outSurfaceControl,

result,

createSurfaceControl(SurfaceControl

outSurfaceControl,

RELAYOUT_RES_SURFACE_CHANGED;}WindowSurfaceController

{//

通过WindowStateAnimator对象创建WindowSurfaceController对象surfaceController

winAnimator.createSurfaceLocked();}

finally

通过WindowSurfaceController将SurfaceController拷贝到outSurfaceControl中outSurfaceControl对应App进程中的ViewRootImpl的mSurfaceControl变量surfaceController.getSurfaceControl(outSurfaceControl);

else

...outSurfaceControl.release();}return

result;}//

为单个WindowState跟踪动画和surface的操作.**///

com.android.server.wm.WindowStateAnimator

class

创建WindowSurfaceControllerWindowSurfaceController

{final

WindowSurfaceController(attrs.getTitle().toString(),

format,

com.android.server.wm.WindowSurfaceController

class

{WindowSurfaceController(String

name,

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);//

...mSurfaceControl

}可以看出WindowSurfaceController是SurfaceControl的包装类通过持有SurfaceControl对象来对Surface进行操作WindowSurfaceController以及SurfaceControl都是在SystemServer进程创建的。

接下来继续跟着SurfaceControl的构造函数看下SurfaceControl的创建具体做了哪些事情。

/***

持有一个由系统合成器管理的Surface对象。

这个SurfaceControl对象由buffer以及如何显示buffer的信息组成。

*

通过构造的Surface对象可以提交数据到buffer用于合成上屏。

*/

public

...assignNativeObject(nativeObject,

callsite);//

OutOfResourcesException;private

void

sRegistry.registerNativeAllocation(this,

nativeObject);}//

记录native层Surface对象的句柄值mNativeObject

mNativeObject

null;}setUnreleasedWarningCallSite(callsite);addToRegistry();}

}从源码可以看出Java层的SurfaceControl对象其实是一个壳其内部的主要实现是在native层的SurfaceControl对象中的通过持有native层的SurfaceControl对象的句柄值对其进行调用。

因此SurfaceControl的关键实现在nativeCreate这个native方法中。

frameworks/base/core/jni/android_view_SurfaceControl.cpp

static

获取SurfaceComposerClient对象SurfaceComposerClient对象负责与SurfaceFlinger进程进行交互spSurfaceComposerClient

client;if

android_view_SurfaceSession_getClient(env,

sessionObj);}

SurfaceComposerClient::getDefault();}SurfaceControl

*parent

reinterpret_castSurfaceControl*(parentObject);spSurfaceControl

surface;//

client-createSurfaceChecked(String8(name.c_str()),

format,

java/lang/IllegalArgumentException,

NULL);return

statusToString(err).c_str());return

reinterpret_castjlong(surface.get());

}从源码中得知通过SurfaceComposerClient调用createSurfaceChecked方法进行native层的SurfaceControl的创建内部通过成员变量mClient跨进程调用到SurfaceFlinger进程mClient的远程实现是SurfaceFlinger进程的Client类。

frameworks/native/libs/gui/SurfaceComposerClient.cpp

status_t

SurfaceComposerClient::createSurfaceChecked(const

String8

请求SurfaceFlinger进程创建一个SurfaceControlbinder::Status

status

mClient-createSurface(std::string(name.c_str()),

flags,

statusTFromBinderStatus(status);//

...

根据CreateSurfaceResult构造SurfaceControl对象并将其返回//

result.handle是一个Binder对象封装了SurfaceFlinger进程的Layer以及SurfaceFlinger*outSurface

new

frameworks/native/libs/gui/SurfaceControl.cpp

SurfaceControl::SurfaceControl(const

client,

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

binder::Status

std::move(metadata));args.parentHandle

parent;//

为App进程的SurfaceControl创建Layerconst

status_t

binderStatusFromStatusT(status);

}//

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

status_t

SurfaceFlinger::createLayer(LayerCreationArgs

args,

ISurfaceComposerClient::eFXSurfaceMask)

{case

ISurfaceComposerClient::eFXSurfaceBufferQueue:case

ISurfaceComposerClient::eFXSurfaceContainer:case

ISurfaceComposerClient::eFXSurfaceBufferState:args.flags

ISurfaceComposerClient::eNoColorFill;[[fallthrough]];case

ISurfaceComposerClient::eFXSurfaceEffect:

{//

layer-getPendingBufferCounter();if

{std::string

layer-getPendingBufferCounterName();mBufferCountTracker.add(outResult.handle-localBinder(),

counterName,

LayerHandle::getLayer(args.parentHandle.promote());uint32_t

outTransformHint;//

outTransformHint);outResult.layerId

layer-sequence;outResult.layerName

String16(layer-getDebugName());return

result;

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

status_t

SurfaceFlinger::createBufferStateLayer(LayerCreationArgs

args,

getFactory().createBufferStateLayer(args);*handle

NO_ERROR;

frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp

spLayer

DefaultFactory::createBufferStateLayer(const

LayerCreationArgs

frameworks/native/services/surfaceflinger/Layer.cpp

Layer::Layer(const

surfaceflinger::LayerCreationArgs

args):

sequence(args.sequence),mFlinger(spSurfaceFlinger::fromExisting(args.flinger)),mName(base::StringPrintf(%s#%d,

args.name.c_str(),

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,

this))

}SurfaceFlinger进程中调用了SurfaceFlinger::createBufferStateLayer方法创建了Layer对象因此SystemServer进程中的SurfaceControl对象对应SurfaceFlinger进程的Layer对象。

上面提到经过App进程到SystemServer进程再到SurfaceFlinger进程最终完成了一系列window相关的对象创建。

最终依次返回并将相关信息跨进程拷贝回App进程。

之后因为App进程的mSurfaceControl处于有效状态此时将会App进程的mSurface进行更新操作。

public

ThreadedRenderer.DrawCallbacks,

{final

mWindowSession.addToDisplayAsUser(mWindow,

mWindowAttributes,

mInsetsController.getRequestedVisibilities(),

inputChannel,

是否开启BLAST取决于SystemServer进程返回的resif

((res

WindowManagerGlobal.ADD_FLAG_USE_BLAST)

{mUseBLASTAdapter

relayoutWindow(WindowManager.LayoutParams

params,

mWindowSession.relayout(mWindow,

params,

WindowManagerGlobal.RELAYOUT_INSETS_PENDING

mTmpFrames,

mSurfaceControl实例可用之后根据mSurfaceControl的Surface信息对mSurface进行更新if

{if

{mSurface.copyFrom(mSurfaceControl);}

else

{updateBlastSurfaceIfNeeded();}//

...}

}在更新mSurface之前会判断是否使用BLAST而是否使用BLAST是在addView的时候由SystemServer进程决定的根据源码可知Android

S开始默认开启BLAST因此最后调用了updateBlastSurfaceIfNeeded方法其内部会调用Surface#transferFrom方法进而拷贝mNativeObject的值。

class

outActiveControls,outAttachedFrame,

}//

com.android.server.wm.WindowManagerService

public

WindowManagerPolicy.WindowManagerFuncs

{//

atm,DisplayWindowSettingsProvider

displayWindowSettingsProvider,SupplierSurfaceControl.Transaction

transactionFactory,FunctionSurfaceSession,

{//

Settings.Global.getInt(resolver,

Settings.Global.DEVELOPMENT_USE_BLAST_ADAPTER_VR,

1;//

requestedVisibleTypes,InputChannel

outInputChannel,

outInsetsState,InsetsSourceControl.Array

outActiveControls,

mPolicy.checkAddPermission(attrs.type,

(res

WindowManagerGlobal.ADD_FLAG_USE_BLAST;}//

...}Binder.restoreCallingIdentity(origId);return

res;}public

ThreadedRenderer.DrawCallbacks,

{final

如果对应的native层的SurfaceControl对象是同一个则直接更新即可不需要重新创建BLASTBufferQueueif

(mBlastBufferQueue

mBlastBufferQueue.isSameSurfaceControl(mSurfaceControl))

{mBlastBufferQueue.update(mSurfaceControl,

mSurfaceSize.x,

mWindowAttributes.format);return;}//

如果更新了SurfaceControl那么销毁并重建BBQBLASTBufferQueue来重置BufferQueue及BLASTBufferQueue的状态.if

(mBlastBufferQueue

{mBlastBufferQueue.destroy();}mBlastBufferQueue

new

mWindowAttributes.format);mBlastBufferQueue.setTransactionHangCallback(sTransactionHangCallback);Surface

blastSurface

mBlastBufferQueue.createSurface();//

Only

recreated.mSurface.transferFrom(blastSurface);}//

...

S开始由App进程创建管理BufferQueue即ViewRootImpl#mBlastBufferQueue。

那BLASTBufferQueue是在什么时候创建的呢查看源码发现其实就是在ViewRootImpl#updateBlastSurfaceIfNeeded方法中创建的。

下面看下BLASTBufferQueue的创建过程。

根据上面的分析得出App进程在创建完SurfaceControl之后会继续创建BLASTBufferQueue并且在创建BLASTBufferQueue之前并没有发现和图像数据跨进程传输相关的代码实现所以不妨假设下BLASTBufferQueue的创建其实就是为跨进程传输图像数据做准备。

android.graphics.BLASTBufferQueue

public

updateDestinationFrame);}private

static

updateDestinationFrame);private

static

}从BLASTBufferQueue的构造函数可以看到和SurfaceControl以及Surface类似都是通过JNI调用到native层去创建对应的对象。

因此Java层的BLASTBufferQueue对象也是native层的BLASTBufferQueue的壳因此进一步分析native层的代码。

frameworks/base/core/jni/android_graphics_BLASTBufferQueue.cpp

static

updateDestinationFrame);queue-incStrong((void*)nativeCreate);return

reinterpret_castjlong(queue.get());

}static

reinterpret_castBLASTBufferQueue*(ptr);queue-update(reinterpret_castSurfaceControl*(surfaceControl),

width,

}native层在创建了BLASTBufferQueue对象之后调用了BLASTBufferQueue::update方法。

frameworks/native/libs/gui/BLASTBufferQueue.cpp

BLASTBufferQueue::BLASTBufferQueue(const

std::string

mSurfaceControl(nullptr),mSize(1,

1),mRequestedSize(mSize),mFormat(PIXEL_FORMAT_RGBA_8888),mTransactionReadyCallback(nullptr),mSyncTransaction(nullptr),mUpdateDestinationFrame(updateDestinationFrame)

{//

先创建BufferQueue然后初始化mProducer以及mConsumercreateBufferQueue(mProducer,

mConsumer);//

因为是在client进程因此为dequeue操作设置超时来保证dequeueBuffer时会阻塞线程。

mProducer-setDequeueTimeout(std::numeric_limitsint64_t::max());//

buffer的默认数量为2mProducer-setMaxDequeuedBufferCount(2);//

封装BufferQueueConsumermBufferItemConsumer

new

BLASTBufferItemConsumer(mConsumer,

GraphicBuffer::USAGE_HW_COMPOSER

GraphicBuffer::USAGE_HW_TEXTURE,

false,

std::to_string(mProducerId);auto

consumerName

std::to_string(mProducerId);mQueuedBufferTrace

QueuedBuffer

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;mNumFrameAvailable

0;TransactionCompletedListener::getInstance()-addQueueStallListener([](const

std::string

BLASTBufferQueue::createBufferQueue(spIGraphicBufferProducer*

outProducer,

将BufferQueueCore传入BBQBufferQueueProducer这样当producer发起调用时可以异步化通过持有的BufferQueueCore将结果返回spIGraphicBufferProducer

producer(new

BufferQueueConsumer(core));consumer-setAllowExtraAcquire(true);*outProducer

consumer;

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)

{int

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

spBufferQueueCore

mBLASTBufferQueue(std::move(bbq))

{}BufferQueueConsumer::BufferQueueConsumer(const

spBufferQueueCore

:mCore(core),mSlots(core-mSlots),mConsumerName()

{}//

frameworks/native/libs/gui/BufferQueueProducer.cpp

BufferQueueProducer::BufferQueueProducer(const

spBufferQueueCore

: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。

virtual

requestBuffer返回GraphicBuffer到第N个slot。

N的时候。

但是如果dequeueBuffer返回的flags表明之前返回的buffers已经失效的话就必须再次调用requestBuffer。

virtual

queueBuffer返回一个填充过的buffer到BufferQueue。

virtual

frameworks/native/libs/gui/BufferQueueConsumer.cpp

BufferQueueConsumer::BufferQueueConsumer(const

spBufferQueueCore

: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。

virtual

slot到BufferQueue中。

releaseBuffer调用时有可能还在访问buffer的内容。

virtual

fence);当完成BLASTBufferQueue的创建之后通过update方法更新持有的SurfaceControl变量将其指向新的SurfaceControl对象。

frameworks/native/libs/gui/BLASTBufferQueue.cpp

void

format;mBufferItemConsumer-setDefaultBufferFormat(convertBufferFormat(format));}const

bool

!SurfaceControl::isSameSurface(mSurfaceControl,

surface);bool

更新持有的SurfaceControl变量mSurfaceControl

surface;SurfaceComposerClient::Transaction

t;if

layer_state_t::eEnableBackpressure,

layer_state_t::eEnableBackpressure);applyTransaction

true;}mTransformHint

mSurfaceControl-getTransformHint();mBufferItemConsumer-setTransformHint(mTransformHint);ui::Size

newSize(width,

{mRequestedSize.set(newSize);mBufferItemConsumer-setDefaultBufferSize(mRequestedSize.width,

NATIVE_WINDOW_SCALING_MODE_FREEZE)

{//

{t.setDestinationFrame(mSurfaceControl,

Rect(newSize));applyTransaction

true;}}}if

mAppliedLastTransactiont.setApplyToken(mApplyToken).apply(false,

true);}

在创建完BLASTBufferQueue之后会通过新创建的BLASTBufferQueue对象创建一个Surface对象并用新的Surface对象更新ViewRootImpl#mSurface主要是将内部持有的native层的句柄值更新为BLASTBufferQueue对象创建的native的句柄值。

public

ThreadedRenderer.DrawCallbacks,

{final

如果对应的native层的SurfaceControl对象是同一个则直接更新即可不需要重新创建BLASTBufferQueueif

(mBlastBufferQueue

mBlastBufferQueue.isSameSurfaceControl(mSurfaceControl))

{mBlastBufferQueue.update(mSurfaceControl,

mSurfaceSize.x,

mWindowAttributes.format);return;}//

如果更新了SurfaceControl那么销毁并重建BBQBLASTBufferQueue来重置BufferQueue及BLASTBufferQueue的状态.if

(mBlastBufferQueue

{mBlastBufferQueue.destroy();}mBlastBufferQueue

new

mWindowAttributes.format);mBlastBufferQueue.setTransactionHangCallback(sTransactionHangCallback);//

通过新创建的BLASTBufferQueue对象创建Surface对象并用新的Surface对象更新mSurfaceSurface

blastSurface

mBlastBufferQueue.createSurface();//

Only

recreated.mSurface.transferFrom(blastSurface);}//

...

}可以看到最终还是BLASTBufferQueue调用nativeGetSurface到了native层去创建Surface对象这里Surface对象就持有了BLASTBufferQueue的mProducer这样就可以通过Surface访问BBQBufferQueueProducer然后通过BBQBufferQueueProducer访问BufferQueueCore最终实现Buffer的访问使用。

public

nativeGetSurface(mNativeObject,

false

frameworks/base/core/jni/android_graphics_BLASTBufferQueue.cpp

static

reinterpret_castBLASTBufferQueue*(ptr);return

android_view_Surface_createFromSurface(env,

queue-getSurface(includeSurfaceControlHandle));

}//

frameworks/native/libs/gui/BLASTBufferQueue.cpp

spSurface

BLASTBufferQueue::getSurface(bool

{std::lock_guard

mSurfaceControl-getHandle();}return

new

frameworks/native/libs/gui/BLASTBufferQueue.cpp

igbp,

frameworks/native/libs/gui/Surface.cpp

bufferProducer,

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)

1;//

首先当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优化服务概述

作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。

百度官方合作伙伴 白帽SEO技术 数据驱动优化 效果长期稳定

SEO优化核心服务

网站技术SEO

  • 网站结构优化 - 提升网站爬虫可访问性
  • 页面速度优化 - 缩短加载时间,提高用户体验
  • 移动端适配 - 确保移动设备友好性
  • HTTPS安全协议 - 提升网站安全性与信任度
  • 结构化数据标记 - 增强搜索结果显示效果

内容优化服务

  • 关键词研究与布局 - 精准定位目标关键词
  • 高质量内容创作 - 原创、专业、有价值的内容
  • Meta标签优化 - 提升点击率和相关性
  • 内容更新策略 - 保持网站内容新鲜度
  • 多媒体内容优化 - 图片、视频SEO优化

外链建设策略

  • 高质量外链获取 - 权威网站链接建设
  • 品牌提及监控 - 追踪品牌在线曝光
  • 行业目录提交 - 提升网站基础权威
  • 社交媒体整合 - 增强内容传播力
  • 链接质量分析 - 避免低质量链接风险

SEO服务方案对比

服务项目 基础套餐 标准套餐 高级定制
关键词优化数量 10-20个核心词 30-50个核心词+长尾词 80-150个全方位覆盖
内容优化 基础页面优化 全站内容优化+每月5篇原创 个性化内容策略+每月15篇原创
技术SEO 基本技术检查 全面技术优化+移动适配 深度技术重构+性能优化
外链建设 每月5-10条 每月20-30条高质量外链 每月50+条多渠道外链
数据报告 月度基础报告 双周详细报告+分析 每周深度报告+策略调整
效果保障 3-6个月见效 2-4个月见效 1-3个月快速见效

SEO优化实施流程

我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:

1

网站诊断分析

全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。

2

关键词策略制定

基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。

3

技术优化实施

解决网站技术问题,优化网站结构,提升页面速度和移动端体验。

4

内容优化建设

创作高质量原创内容,优化现有页面,建立内容更新机制。

5

外链建设推广

获取高质量外部链接,建立品牌在线影响力,提升网站权威度。

6

数据监控调整

持续监控排名、流量和转化数据,根据效果调整优化策略。

SEO优化常见问题

SEO优化一般需要多长时间才能看到效果?
SEO是一个渐进的过程,通常需要3-6个月才能看到明显效果。具体时间取决于网站现状、竞争程度和优化强度。我们的标准套餐一般在2-4个月内开始显现效果,高级定制方案可能在1-3个月内就能看到初步成果。
你们使用白帽SEO技术还是黑帽技术?
我们始终坚持使用白帽SEO技术,遵循搜索引擎的官方指南。我们的优化策略注重长期效果和可持续性,绝不使用任何可能导致网站被惩罚的违规手段。作为百度官方合作伙伴,我们承诺提供安全、合规的SEO服务。
SEO优化后效果能持续多久?
通过我们的白帽SEO策略获得的排名和流量具有长期稳定性。一旦网站达到理想排名,只需适当的维护和更新,效果可以持续数年。我们提供优化后维护服务,确保您的网站长期保持竞争优势。
你们提供SEO优化效果保障吗?
我们提供基于数据的SEO效果承诺。根据服务套餐不同,我们承诺在约定时间内将核心关键词优化到指定排名位置,或实现约定的自然流量增长目标。所有承诺都会在服务合同中明确约定,并提供详细的KPI衡量标准。

SEO优化效果数据

基于我们服务的客户数据统计,平均优化效果如下:

+85%
自然搜索流量提升
+120%
关键词排名数量
+60%
网站转化率提升
3-6月
平均见效周期

行业案例 - 制造业

  • 优化前:日均自然流量120,核心词无排名
  • 优化6个月后:日均自然流量950,15个核心词首页排名
  • 效果提升:流量增长692%,询盘量增加320%

行业案例 - 电商

  • 优化前:月均自然订单50单,转化率1.2%
  • 优化4个月后:月均自然订单210单,转化率2.8%
  • 效果提升:订单增长320%,转化率提升133%

行业案例 - 教育

  • 优化前:月均咨询量35个,主要依赖付费广告
  • 优化5个月后:月均咨询量180个,自然流量占比65%
  • 效果提升:咨询量增长414%,营销成本降低57%

为什么选择我们的SEO服务

专业团队

  • 10年以上SEO经验专家带队
  • 百度、Google认证工程师
  • 内容创作、技术开发、数据分析多领域团队
  • 持续培训保持技术领先

数据驱动

  • 自主研发SEO分析工具
  • 实时排名监控系统
  • 竞争对手深度分析
  • 效果可视化报告

透明合作

  • 清晰的服务内容和价格
  • 定期进展汇报和沟通
  • 效果数据实时可查
  • 灵活的合同条款

我们的SEO服务理念

我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。

提交需求或反馈

Demand feedback