از 27 مارس 2025، توصیه می کنیم از android-latest-release به جای aosp-main برای ساختن و کمک به AOSP استفاده کنید. برای اطلاعات بیشتر، به تغییرات AOSP مراجعه کنید.
با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
اشیاء سطحی به برنامه ها امکان می دهند تصاویر را برای نمایش روی صفحه نمایش ارائه دهند. رابط های SurfaceHolder برنامه ها را قادر می سازد تا سطوح را ویرایش و کنترل کنند.
سطح
سطح یک رابط برای یک تولید کننده برای تبادل بافر با مصرف کننده است.
BufferQueue برای سطح نمایش معمولاً برای بافر سه گانه پیکربندی می شود. بافرها بر اساس تقاضا تخصیص داده می شوند، بنابراین اگر تولید کننده بافرها را به اندازه کافی آهسته تولید کند، مثلاً با سرعت 30 فریم در ثانیه در یک نمایشگر 60 فریم در ثانیه، ممکن است فقط دو بافر اختصاص داده شده در صف وجود داشته باشد. تخصیص بافرهای درخواستی به به حداقل رساندن مصرف حافظه کمک می کند. می توانید خلاصه ای از بافرهای مرتبط با هر لایه را در خروجی dumpsys SurfaceFlinger مشاهده کنید.
اکثر مشتریان با استفاده از OpenGL ES یا Vulkan روی سطوح رندر می دهند. با این حال، برخی از مشتریان با استفاده از بوم بر روی سطوح نمایش می دهند.
رندر بوم
اجرای بوم توسط کتابخانه گرافیک اسکیا ارائه شده است. اگر می خواهید یک مستطیل بکشید، Canvas API را فراخوانی می کنید که بایت ها را به طور مناسب در یک بافر تنظیم می کند. برای اطمینان از اینکه یک بافر توسط دو کلاینت بهطور همزمان بهروزرسانی نمیشود یا هنگام نمایش روی آن نوشته نمیشود، بافر را قفل کنید تا به آن دسترسی داشته باشید. برای کار با قفل های بوم از دستورات زیر استفاده کنید:
lockCanvas() بافر را برای رندر کردن در CPU قفل می کند و یک Canvas را برای استفاده برای ترسیم برمی گرداند.
lockHardwareCanvas() بافر را برای رندر در GPU قفل می کند و یک بوم را برای استفاده برای طراحی برمی گرداند.
اولین باری که سازنده از یک BufferQueue درخواست بافر می کند، بافر تخصیص داده می شود و مقدار اولیه آن صفر می شود. برای جلوگیری از به اشتراک گذاری ناخواسته داده ها بین فرآیندها، مقداردهی اولیه ضروری است. با این حال، اگر از یک بافر دوباره استفاده کنید، محتویات قبلی همچنان وجود دارند. اگر مکرراً lockCanvas() و unlockCanvasAndPost() بدون ترسیم چیزی فراخوانی کنید، تولید کننده بین فریم های قبلی رندر شده چرخه می زند.
کد قفل/بازکردن سطح، ارجاعی به بافر رندر شده قبلی نگه می دارد. اگر هنگام قفل کردن سطح یک منطقه کثیف را مشخص کنید، پیکسل های غیر کثیف را از بافر قبلی کپی می کند. SurfaceFlinger یا HWC معمولاً بافر را مدیریت می کنند. اما از آنجایی که ما فقط باید از بافر بخوانیم، نیازی به منتظر ماندن برای دسترسی انحصاری نیست.
SurfaceHolder
SurfaceHolder رابطی است که سیستم از آن برای به اشتراک گذاشتن مالکیت سطوح با برنامه ها استفاده می کند. برخی از کلاینتهایی که با سطوح کار میکنند، یک SurfaceHolder میخواهند، زیرا APIها برای دریافت و تنظیم پارامترهای سطح از طریق SurfaceHolder پیادهسازی میشوند. SurfaceView حاوی SurfaceHolder است.
اکثر کامپوننت هایی که با یک view تعامل دارند، یک SurfaceHolder دارند. برخی از API های دیگر مانند MediaCodec روی خود سطح کار می کنند.
محتوا و نمونه کدها در این صفحه مشمول پروانههای توصیفشده در پروانه محتوا هستند. جاوا و OpenJDK علامتهای تجاری یا علامتهای تجاری ثبتشده Oracle و/یا وابستههای آن هستند.
تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی.
[[["درک آسان","easyToUnderstand","thumb-up"],["مشکلم را برطرف کرد","solvedMyProblem","thumb-up"],["غیره","otherUp","thumb-up"]],[["اطلاعاتی که نیاز دارم وجود ندارد","missingTheInformationINeed","thumb-down"],["بیشازحد پیچیده/ مراحل بسیار زیاد","tooComplicatedTooManySteps","thumb-down"],["قدیمی","outOfDate","thumb-down"],["مشکل ترجمه","translationIssue","thumb-down"],["مشکل کد / نمونهها","samplesCodeIssue","thumb-down"],["غیره","otherDown","thumb-down"]],["تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی."],[],[],null,["# Surface and SurfaceHolder\n\nSurface objects enable apps to render images to be presented on screens.\nSurfaceHolder interfaces enable apps to edit and control surfaces.\n\nSurface\n-------\n\nA [surface](https://developer.android.com/reference/android/view/Surface.html) is an interface for a producer to exchange buffers\nwith a consumer.\n\nThe BufferQueue for a display surface is typically configured for\ntriple-buffering. Buffers are allocated on demand, so if the producer\ngenerates buffers slowly enough, such as at 30 fps on a 60 fps\ndisplay, there might only be two allocated buffers in the queue.\nAllocating buffers on demand helps\nminimize memory consumption. You can see a summary of the buffers associated\nwith every layer in the `dumpsys SurfaceFlinger` output.\n\nMost clients render onto surfaces using [OpenGL ES](/docs/core/graphics/arch-egl-opengl) or [Vulkan](/docs/core/graphics/arch-vulkan). However, some clients render\nonto surfaces using a canvas.\n\n\n### Canvas rendering\n\nThe canvas implementation is provided by the\n[Skia Graphics Library](https://skia.org/).\nIf you want to draw a rectangle, you call the Canvas API, which sets bytes in a\nbuffer appropriately. To ensure that a buffer isn't updated by two clients at\nonce, or written to while being displayed, lock the buffer to access\nit. Use the following commands to work with canvas locks:\n\n- [`lockCanvas()`](https://developer.android.com/reference/android/view/Surface.html#lockCanvas(android.graphics.Rect)) locks the buffer for rendering on the CPU and returns a Canvas to use for drawing.\n- [`unlockCanvasAndPost()`](https://developer.android.com/reference/android/view/Surface.html#unlockCanvasAndPost(android.graphics.Canvas)) unlocks the buffer and sends it to the compositor.\n- [`lockHardwareCanvas()`](https://developer.android.com/reference/android/view/Surface.html#lockHardwareCanvas()) locks the buffer for rendering on the GPU and returns a canvas to use for drawing.\n\n| **Note:** The canvas obtained when an app locks a surface with `lockCanvas()` is never hardware accelerated.\n| **Caution:** You can't draw on a surface with GLES or send it frames from a video decoder if you've ever called `lockCanvas()`. `lockCanvas()` connects the CPU renderer to the producer side of the BufferQueue and doesn't disconnect until the surface is destroyed. The canvas-based CPU renderer can't be disconnected and reconnected to a surface, unlike most producers (like GLES or Vulkan).\n\nThe first time the producer requests a buffer from a BufferQueue, the\nbuffer is\nallocated and initialized to zero. Initialization is necessary to avoid\ninadvertently sharing data between processes. However, if you reuse a buffer,\nthe previous contents are still present. If you repeatedly call\n`lockCanvas()` and `unlockCanvasAndPost()` without\ndrawing anything, the producer cycles between previously rendered frames.\n\nThe surface lock/unlock code keeps a reference to the previously rendered\nbuffer. If you specify a dirty region when locking the surface, it copies\nthe nondirty pixels from the previous buffer. SurfaceFlinger or HWC typically\nhandle the buffer; but because we only need to read from\nthe buffer, there's no need to wait for exclusive access.\n\nSurfaceHolder\n-------------\n\nA [SurfaceHolder](https://developer.android.com/reference/android/view/SurfaceHolder.html) is an interface the system uses to share ownership of\nsurfaces with apps. Some clients that work with surfaces want a SurfaceHolder,\nbecause APIs to get and set surface parameters are implemented through a\nSurfaceHolder. A [SurfaceView](/docs/core/graphics/arch-sv-glsv) contains\na SurfaceHolder.\n\nMost components that interact with a view involve a SurfaceHolder.\nSome other APIs, such as MediaCodec, operate on the surface itself."]]