شتاب سخت‌افزاری (بازدیدها)

مفاهیم و پیاده‌سازی Jetpack Compose

از اندروید ۳.۰ (سطح API ۱۱)، خط لوله رندر دوبعدی اندروید از شتاب سخت‌افزاری پشتیبانی می‌کند، به این معنی که تمام عملیات ترسیم که روی بوم View انجام می‌شوند از GPU استفاده می‌کنند. به دلیل افزایش منابع مورد نیاز برای فعال کردن شتاب سخت‌افزاری، برنامه شما رم بیشتری مصرف خواهد کرد.

اگر سطح Target API شما >=14 باشد، شتاب‌دهنده سخت‌افزاری به طور پیش‌فرض فعال است، اما می‌توان آن را به طور صریح نیز فعال کرد. اگر برنامه شما فقط از نماهای استاندارد و Drawable ها استفاده می‌کند، فعال کردن آن به صورت سراسری نباید هیچ اثر نامطلوبی در طراحی ایجاد کند. با این حال، از آنجا که شتاب‌دهنده سخت‌افزاری برای همه عملیات طراحی دوبعدی پشتیبانی نمی‌شود، فعال کردن آن ممکن است بر برخی از نماهای سفارشی یا فراخوانی‌های طراحی شما تأثیر بگذارد. مشکلات معمولاً خود را به صورت عناصر نامرئی، استثنائات یا پیکسل‌های رندر شده اشتباه نشان می‌دهند. برای رفع این مشکل، اندروید به شما این امکان را می‌دهد که شتاب‌دهنده سخت‌افزاری را در چندین سطح فعال یا غیرفعال کنید. به بخش کنترل شتاب‌دهنده سخت‌افزاری مراجعه کنید.

اگر برنامه شما طراحی سفارشی انجام می‌دهد، برنامه خود را روی دستگاه‌های سخت‌افزاری واقعی با شتاب‌دهنده سخت‌افزاری فعال آزمایش کنید تا هرگونه مشکلی را پیدا کنید. بخش پشتیبانی از عملیات طراحی، مشکلات شناخته‌شده با شتاب‌دهنده سخت‌افزاری و نحوه حل آنها را شرح می‌دهد.

همچنین به OpenGL با APIهای چارچوب و Renderscript مراجعه کنید.

کنترل شتاب سخت‌افزاری

شما می‌توانید شتاب سخت‌افزاری را در سطوح زیر کنترل کنید:

  • کاربرد
  • فعالیت
  • پنجره
  • مشاهده

سطح برنامه

در فایل مانیفست اندروید خود، ویژگی زیر را به تگ <application> اضافه کنید تا شتاب‌دهنده سخت‌افزاری برای کل برنامه شما فعال شود:

<application android:hardwareAccelerated="true" ...>

سطح فعالیت

اگر برنامه شما با فعال بودن شتاب سخت‌افزاری به صورت سراسری به درستی رفتار نمی‌کند، می‌توانید آن را برای فعالیت‌های منفرد نیز کنترل کنید. برای فعال یا غیرفعال کردن شتاب سخت‌افزاری در سطح فعالیت، می‌توانید از ویژگی android:hardwareAccelerated برای عنصر <activity> استفاده کنید. مثال زیر شتاب سخت‌افزاری را برای کل برنامه فعال می‌کند اما آن را برای یک فعالیت غیرفعال می‌کند:

<application android:hardwareAccelerated="true">
    <activity ... />
    <activity android:hardwareAccelerated="false" />
</application>

سطح پنجره

اگر به کنترل دقیق‌تری نیاز دارید، می‌توانید شتاب‌دهنده سخت‌افزاری را برای یک پنجره مشخص با کد زیر فعال کنید:

کاتلین

window.setFlags(
        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
        WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
)

جاوا

getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

سطح مشاهده

شما می‌توانید شتاب سخت‌افزاری را برای یک نمای خاص در زمان اجرا با کد زیر غیرفعال کنید:

کاتلین

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)

جاوا

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

تعیین اینکه آیا یک نما از شتاب‌دهنده سخت‌افزاری استفاده می‌کند یا خیر

گاهی اوقات برای یک برنامه مفید است که بداند آیا در حال حاضر از شتاب‌دهنده سخت‌افزاری استفاده می‌کند یا خیر، به خصوص برای مواردی مانند نماهای سفارشی. این امر به ویژه در صورتی مفید است که برنامه شما طراحی‌های سفارشی زیادی انجام دهد و همه عملیات به درستی توسط خط لوله رندر جدید پشتیبانی نشوند.

دو روش مختلف برای بررسی اینکه آیا برنامه از شتاب‌دهنده سخت‌افزاری پشتیبانی می‌کند یا خیر وجود دارد:

  • اگر View به یک پنجره‌ی شتاب‌دهنده‌ی سخت‌افزاری متصل باشد، View.isHardwareAccelerated مقدار true را برمی‌گرداند.

  • اگر Canvas از شتاب‌دهنده سخت‌افزاری استفاده کند، Canvas.isHardwareAccelerated true را برمی‌گرداند.

اگر مجبورید این بررسی را در کد طراحی خود انجام دهید، در صورت امکان از Canvas.isHardwareAccelerated به جای View.isHardwareAccelerated استفاده کنید. وقتی یک نما به یک پنجره شتاب‌دهنده سخت‌افزاری متصل است، همچنان می‌توان آن را با استفاده از یک Canvas بدون شتاب‌دهنده سخت‌افزاری ترسیم کرد. این اتفاق می‌افتد، برای مثال، هنگام ترسیم یک نما در یک بیت‌مپ برای اهداف ذخیره‌سازی.

مدل‌های نقاشی اندروید

وقتی شتاب‌دهنده سخت‌افزاری فعال باشد، چارچوب اندروید از یک مدل طراحی جدید استفاده می‌کند که از لیست‌های نمایش برای رندر کردن برنامه شما روی صفحه استفاده می‌کند. برای درک کامل لیست‌های نمایش و اینکه چگونه ممکن است بر برنامه شما تأثیر بگذارند، مفید است که بدانید اندروید چگونه نماها را بدون شتاب‌دهنده سخت‌افزاری نیز ترسیم می‌کند. بخش‌های زیر مدل‌های طراحی مبتنی بر نرم‌افزار و شتاب‌دهنده سخت‌افزاری را شرح می‌دهند.

مدل طراحی مبتنی بر نرم‌افزار

در مدل ترسیم نرم‌افزاری، نماها با دو مرحله زیر ترسیم می‌شوند:

  1. سلسله مراتب را باطل کنید
  2. سلسله مراتب را رسم کنید

هر زمان که یک برنامه نیاز به به‌روزرسانی بخشی از رابط کاربری خود داشته باشد، تابع invalidate() (یا یکی از انواع آن) را روی هر نمایی که محتوا را تغییر داده است، فراخوانی می‌کند. پیام‌های نامعتبرسازی در تمام سلسله مراتب نماها منتشر می‌شوند تا مناطقی از صفحه که باید دوباره ترسیم شوند (منطقه کثیف) را محاسبه کنند. سپس سیستم اندروید هر نمایی را در سلسله مراتب که با منطقه کثیف تلاقی دارد، ترسیم می‌کند. متأسفانه، این مدل ترسیم دو اشکال دارد:

  • اولاً، این مدل نیاز به اجرای کدهای زیادی در هر بار رسم دارد. برای مثال، اگر برنامه شما تابع invalidate روی یک دکمه فراخوانی کند و آن دکمه روی یک نمای دیگر قرار گیرد، سیستم اندروید نمای مورد نظر را دوباره رسم می‌کند، حتی اگر تغییری نکرده باشد.

  • مشکل دوم این است که مدل طراحی می‌تواند اشکالات موجود در برنامه شما را پنهان کند. از آنجایی که سیستم اندروید نماها را هنگام برخورد با ناحیه کثیف دوباره طراحی می‌کند، ممکن است نمایی که محتوای آن را تغییر داده‌اید، حتی اگر invalidate روی آن فراخوانی نشده باشد، دوباره طراحی شود. وقتی این اتفاق می‌افتد، شما برای به دست آوردن رفتار مناسب به یک نمای دیگر که نامعتبر شده است، متکی هستید. این رفتار می‌تواند هر بار که برنامه خود را تغییر می‌دهید تغییر کند. به همین دلیل، همیشه باید هر زمان که داده‌ها یا وضعیتی را که بر کد طراحی نما تأثیر می‌گذارد، تغییر می‌دهید invalidate روی نماهای سفارشی خود فراخوانی کنید.

مدل طراحی شتاب‌دهنده سخت‌افزاری

سیستم اندروید هنوز invalidate و draw برای درخواست به‌روزرسانی صفحه و رندر کردن نماها استفاده می‌کند، اما ترسیم واقعی را به طور متفاوتی مدیریت می‌کند. سیستم اندروید به جای اجرای فوری دستورات ترسیم، آنها را در لیست‌های نمایش ثبت می‌کند که شامل خروجی کد ترسیم سلسله مراتب نماها هستند. بهینه‌سازی دیگر این است که سیستم اندروید فقط باید لیست‌های نمایش نماهایی را که با فراخوانی invalidate به عنوان dirty علامت‌گذاری شده‌اند، ثبت و به‌روزرسانی کند. نماهایی که نامعتبر نشده‌اند را می‌توان با صدور مجدد لیست نمایش ضبط شده قبلی، دوباره ترسیم کرد. مدل ترسیم جدید شامل سه مرحله است:

  1. سلسله مراتب را باطل کنید

  2. لیست‌های نمایش را ثبت و به‌روزرسانی کنید

  3. فهرست‌های نمایشی را رسم کنید

با این مدل، نمی‌توانید برای اجرای متد draw یک view که ناحیه dirty را قطع می‌کند، به آن تکیه کنید. برای اطمینان از اینکه سیستم اندروید لیست نمایش یک view را ثبت می‌کند، باید تابع invalidate فراخوانی کنید. فراموش کردن این کار باعث می‌شود که یک view حتی پس از تغییر، به همان شکل باقی بماند.

استفاده از فهرست‌های نمایش همچنین به عملکرد انیمیشن کمک می‌کند، زیرا تنظیم ویژگی‌های خاص، مانند آلفا یا چرخش، نیازی به نامعتبر کردن نمای هدف ندارد (این کار به صورت خودکار انجام می‌شود). این بهینه‌سازی همچنین در مورد نماهای دارای فهرست‌های نمایش (هر نمایی که برنامه شما با شتاب‌دهنده سخت‌افزاری کار می‌کند) اعمال می‌شود. به عنوان مثال، فرض کنید یک LinearLayout وجود دارد که شامل یک ListView بالای یک Button است. فهرست نمایش برای LinearLayout به این شکل است:

  • DrawDisplayList(ListView)
  • DrawDisplayList(Button)

حالا فرض کنید که می‌خواهید میزان شفافیت ListView را تغییر دهید. پس از فراخوانی setAlpha(0.5f) در ListView ، لیست نمایش اکنون شامل موارد زیر است:

  • SaveLayerAlpha(0.5)

  • DrawDisplayList(ListView)

  • Restore

  • DrawDisplayList(Button)

کد ترسیم پیچیده ListView اجرا نشد. در عوض، سیستم فقط لیست نمایش LinearLayout بسیار ساده‌تر را به‌روزرسانی کرد. در برنامه‌ای که شتاب‌دهنده سخت‌افزاری فعال نباشد، کد ترسیم لیست و والد آن دوباره اجرا می‌شوند.

پشتیبانی از عملیات ترسیم

وقتی سخت‌افزار شتاب‌دهی می‌شود، خط لوله رندر دوبعدی از رایج‌ترین عملیات طراحی Canvas و همچنین بسیاری از عملیات کم‌استفاده‌تر پشتیبانی می‌کند. تمام عملیات طراحی که برای رندر برنامه‌هایی که با اندروید عرضه می‌شوند، ویجت‌ها و طرح‌بندی‌های پیش‌فرض و جلوه‌های بصری پیشرفته رایج مانند بازتاب‌ها و بافت‌های کاشی‌کاری شده استفاده می‌شوند، پشتیبانی می‌شوند.

جدول زیر سطح پشتیبانی عملیات مختلف را در سطوح مختلف API شرح می‌دهد:

اولین سطح API پشتیبانی شده
بوم نقاشی
تابع drawBitmapMesh() (آرایه رنگ‌ها) ۱۸
رسم تصویر() ۲۳
تابع ()drawPosText ۱۶
رسم متن روی مسیر () ۱۶
رسم رئوس () ۲۹
تابع ()setDrawFilter ۱۶
کلیپ‌پَچ() ۱۸
کلیپ‌ریجن() ۱۸
clipRect(Region.Op.XOR) ۱۸
clipRect(اختلاف عملیات منطقه) ۱۸
clipRect(Region.Op.ReverseDifference) ۱۸
clipRect() با چرخش/پرسپکتیو ۱۸
رنگ
setAntiAlias() (برای متن) ۱۸
تابع ()setAntiAlias ​​(برای خطوط) ۱۶
تابع setFilterBitmap() ۱۷
تابع ()setLinearText
فیلتر ماسک تنظیم‌شده()
تابع ()setPathEffect (برای خطوط) ۲۸
setShadowLayer() (غیر از متن) ۲۸
تابع ()setStrokeCap ​​(برای خطوط) ۱۸
تابع ()setStrokeCap ​​(برای امتیازها) ۱۹
تابع setSubpixelText() ۲۸
ایکس‌فرمود
PorterDuff.Mode.DARKEN (فریم بافر) ۲۸
PorterDuff.Mode.LIGHTEN (فریم بافر) ۲۸
PorterDuff.Mode.OVERLAY (بافر فریم) ۲۸
سایه‌زن
ComposeShader درون ComposeShader ۲۸
شیدرهای هم نوع درون ComposeShader ۲۸
ماتریس محلی روی ComposeShader ۱۸

مقیاس‌بندی بوم

خط لوله رندر دوبعدی با شتاب‌دهنده سخت‌افزاری ابتدا برای پشتیبانی از ترسیم بدون مقیاس ساخته شد، و برخی از عملیات ترسیم در مقادیر مقیاس بالاتر کیفیت را به طور قابل توجهی کاهش می‌دهند. این عملیات به صورت بافت‌هایی که در مقیاس ۱.۰ ترسیم شده‌اند و توسط GPU تبدیل می‌شوند، پیاده‌سازی می‌شوند. با شروع از سطح API 28، تمام عملیات ترسیم می‌توانند بدون مشکل مقیاس‌بندی شوند.

جدول زیر نشان می‌دهد که چه زمانی پیاده‌سازی برای مدیریت صحیح مقیاس‌های بزرگ تغییر داده شده است:

عملیات ترسیم که باید مقیاس‌بندی شود اولین سطح API پشتیبانی شده
رسم متن () ۱۸
تابع ()drawPosText ۲۸
رسم متن روی مسیر () ۲۸
اشکال ساده ۱۷
اشکال پیچیده ۲۸
رسم مسیر () ۲۸
لایه سایه ۲۸

اگر برنامه شما تحت تأثیر هر یک از این ویژگی‌ها یا محدودیت‌های از دست رفته قرار دارد، می‌توانید با فراخوانی setLayerType(View.LAYER_TYPE_SOFTWARE, null) شتاب سخت‌افزاری را فقط برای بخش آسیب‌دیده برنامه خود غیرفعال کنید. به این ترتیب، همچنان می‌توانید از شتاب سخت‌افزاری در هر جای دیگر استفاده کنید. برای اطلاعات بیشتر در مورد نحوه فعال و غیرفعال کردن شتاب سخت‌افزاری در سطوح مختلف برنامه خود، به کنترل شتاب سخت‌افزاری مراجعه کنید.

مشاهده لایه‌ها

در تمام نسخه‌های اندروید، نماها (views) قابلیت رندر شدن در بافرهای خارج از صفحه را داشته‌اند، چه با استفاده از حافظه نهان (cache) طراحی نما، و چه با استفاده از Canvas.saveLayer . بافرهای خارج از صفحه یا لایه‌ها، کاربردهای مختلفی دارند. می‌توانید از آنها برای بهبود عملکرد هنگام متحرک‌سازی نماهای پیچیده یا اعمال جلوه‌های ترکیبی استفاده کنید. به عنوان مثال، می‌توانید با استفاده از Canvas.saveLayer جلوه‌های محو شدن (fade effects) را پیاده‌سازی کنید تا یک نما (view) به طور موقت در یک لایه رندر شود و سپس با یک ضریب شفافیت (opacity factor) دوباره روی صفحه ترکیب شود.

از اندروید ۳.۰ (سطح API ۱۱)، با استفاده از متد View.setLayerType کنترل بیشتری بر نحوه و زمان استفاده از لایه‌ها دارید. این API دو پارامتر می‌گیرد: نوع لایه‌ای که می‌خواهید استفاده کنید و یک شیء Paint اختیاری که نحوه ترکیب لایه را توصیف می‌کند. می‌توانید از پارامتر Paint برای اعمال فیلترهای رنگی، حالت‌های ترکیبی ویژه یا میزان شفافیت به یک لایه استفاده کنید. یک نما می‌تواند از یکی از سه نوع لایه زیر استفاده کند:

  • LAYER_TYPE_NONE : نما به طور عادی رندر می‌شود و توسط بافر خارج از صفحه پشتیبانی نمی‌شود. این رفتار پیش‌فرض است.

  • LAYER_TYPE_HARDWARE : اگر برنامه از شتاب‌دهنده سخت‌افزاری استفاده کند، نما به صورت سخت‌افزاری در یک بافت سخت‌افزاری رندر می‌شود. اگر برنامه از شتاب‌دهنده سخت‌افزاری استفاده نکند، این نوع لایه مانند LAYER_TYPE_SOFTWARE رفتار می‌کند.

  • LAYER_TYPE_SOFTWARE : نما در نرم‌افزار به صورت یک بیت‌مپ رندر می‌شود.

نوع لایه‌ای که استفاده می‌کنید به هدف شما بستگی دارد:

  • عملکرد : از یک نوع لایه سخت‌افزاری برای رندر کردن یک نما به یک بافت سخت‌افزاری استفاده کنید. هنگامی که یک نما به یک لایه رندر می‌شود، کد طراحی آن تا زمانی که فراخوانی‌های نما invalidate ، لازم نیست اجرا شود. برخی از انیمیشن‌ها، مانند انیمیشن‌های آلفا، می‌توانند مستقیماً روی لایه اعمال شوند، که برای GPU بسیار کارآمد است.

  • جلوه‌های بصری : از یک نوع لایه سخت‌افزاری یا نرم‌افزاری و یک Paint برای اعمال جلوه‌های بصری خاص به یک نما استفاده کنید. برای مثال، می‌توانید با استفاده از ColorMatrixColorFilter یک نما را به صورت سیاه و سفید ترسیم کنید.

  • سازگاری : از یک نوع لایه نرم‌افزاری برای رندر کردن اجباری یک نما در نرم‌افزار استفاده کنید. اگر نمایی که با شتاب‌دهنده سخت‌افزاری (مثلاً اگر کل برنامه شما با شتاب‌دهنده سخت‌افزاری) رندر می‌شود، مشکلات رندر دارد، این یک راه آسان برای دور زدن محدودیت‌های خط لوله رندر سخت‌افزاری است.

مشاهده لایه‌ها و انیمیشن‌ها

لایه‌های سخت‌افزاری می‌توانند انیمیشن‌های سریع‌تر و روان‌تری را ارائه دهند، زمانی که برنامه شما از شتاب‌دهنده سخت‌افزاری استفاده می‌کند. اجرای یک انیمیشن با سرعت ۶۰ فریم در ثانیه همیشه هنگام انیمیشن‌سازی نماهای پیچیده که عملیات طراحی زیادی را انجام می‌دهند، امکان‌پذیر نیست. این مشکل را می‌توان با استفاده از لایه‌های سخت‌افزاری برای رندر کردن نما به یک بافت سخت‌افزاری کاهش داد. سپس می‌توان از بافت سخت‌افزاری برای متحرک‌سازی نما استفاده کرد و نیاز به ترسیم مجدد مداوم خود توسط نما هنگام انیمیشن‌سازی را از بین برد. نما دوباره ترسیم نمی‌شود مگر اینکه ویژگی‌های نما را تغییر دهید، که invalidate را فراخوانی می‌کند، یا اگر invalidate به صورت دستی فراخوانی کنید. اگر در برنامه خود یک انیمیشن اجرا می‌کنید و نتایج روان مورد نظر خود را به دست نمی‌آورید، فعال کردن لایه‌های سخت‌افزاری را در نماهای متحرک خود در نظر بگیرید.

وقتی یک نما توسط یک لایه سخت‌افزاری پشتیبانی می‌شود، برخی از ویژگی‌های آن توسط نحوه ترکیب لایه روی صفحه مدیریت می‌شوند. تنظیم این ویژگی‌ها کارآمد خواهد بود زیرا نیازی به نامعتبرسازی و ترسیم مجدد نما ندارند. در زیر لیستی از ویژگی‌هایی که بر نحوه ترکیب لایه تأثیر می‌گذارند، آمده است. فراخوانی تنظیم‌کننده برای هر یک از این ویژگی‌ها منجر به نامعتبرسازی بهینه و عدم ترسیم مجدد نمای مورد نظر می‌شود:

  • alpha : میزان شفافیت لایه را تغییر می‌دهد.

  • x ، y ، translationX ، translationY : موقعیت لایه را تغییر می‌دهد

  • scaleX ، scaleY : اندازه لایه را تغییر می‌دهد

  • rotation ، rotationX ، rotationY : جهت‌گیری لایه را در فضای سه‌بعدی تغییر می‌دهد.

  • pivotX ، pivotY : مبدا تبدیلات لایه را تغییر می‌دهد.

این ویژگی‌ها، نام‌هایی هستند که هنگام متحرک‌سازی یک نما با استفاده از ObjectAnimator استفاده می‌شوند. اگر می‌خواهید به این ویژگی‌ها دسترسی داشته باشید، setter یا getter مناسب را فراخوانی کنید. برای مثال، برای تغییر ویژگی alpha، setAlpha را فراخوانی کنید. قطعه کد زیر کارآمدترین روش برای چرخش یک نما به صورت سه‌بعدی حول محور Y را نشان می‌دهد:

کاتلین

view.setLayerType(View.LAYER_TYPE_HARDWARE, null)
ObjectAnimator.ofFloat(view, "rotationY", 180f).start()

جاوا

view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator.ofFloat(view, "rotationY", 180).start();

از آنجا که لایه‌های سخت‌افزاری حافظه ویدئویی را مصرف می‌کنند، اکیداً توصیه می‌شود که آنها را فقط در طول انیمیشن فعال کنید و پس از اتمام انیمیشن، غیرفعال کنید. می‌توانید این کار را با استفاده از شنونده‌های انیمیشن انجام دهید:

کاتلین

view.setLayerType(View.LAYER_TYPE_HARDWARE, null)
ObjectAnimator.ofFloat(view, "rotationY", 180f).apply {
    addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator) {
            view.setLayerType(View.LAYER_TYPE_NONE, null)
        }
    })
    start()
}

جاوا

view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotationY", 180);
animator.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        view.setLayerType(View.LAYER_TYPE_NONE, null);
    }
});
animator.start();

برای اطلاعات بیشتر در مورد انیمیشن املاک، به انیمیشن املاک مراجعه کنید.

نکات و ترفندها

تغییر به گرافیک دوبعدی شتاب‌دهنده سخت‌افزاری می‌تواند فوراً عملکرد را افزایش دهد، اما شما همچنان باید برنامه خود را طوری طراحی کنید که با پیروی از این توصیه‌ها، از GPU به طور مؤثر استفاده کند:

تعداد بازدیدها را در برنامه خود کاهش دهید
هرچه سیستم مجبور به ترسیم نماهای بیشتری باشد، کندتر خواهد بود. این موضوع در مورد خط لوله رندر نرم‌افزار نیز صدق می‌کند. کاهش نماها یکی از ساده‌ترین راه‌ها برای بهینه‌سازی رابط کاربری شماست.
از برداشت بیش از حد خودداری کنید
لایه‌های زیادی را روی هم نکشید. هر نمایی را که کاملاً توسط نماهای مات دیگر در بالای آن پنهان شده است، حذف کنید. اگر نیاز دارید چندین لایه را که روی هم ترکیب شده‌اند، رسم کنید، ادغام آنها را در یک لایه واحد در نظر بگیرید. یک قانون کلی خوب با سخت‌افزار فعلی این است که بیش از ۲.۵ برابر تعداد پیکسل‌های روی صفحه در هر فریم (پیکسل‌های شفاف در یک بیت‌مپ) رسم نکنید.
اشیاء رندر را در متدهای رسم ایجاد نکنید
یک اشتباه رایج این است که هر بار که یک متد رندر فراخوانی می‌شود، یک Paint یا Path جدید ایجاد شود. این کار باعث می‌شود Garbage Collector بیشتر اجرا شود و همچنین از کش‌ها و بهینه‌سازی‌ها در خط لوله سخت‌افزاری جلوگیری می‌کند.
شکل‌ها را زیاد تغییر ندهید
برای مثال، اشکال، مسیرها و دایره‌های پیچیده با استفاده از ماسک‌های بافت رندر می‌شوند. هر بار که مسیری را ایجاد یا اصلاح می‌کنید، خط لوله سخت‌افزاری یک ماسک جدید ایجاد می‌کند که می‌تواند پرهزینه باشد.
بیت‌مپ‌ها را زیاد تغییر ندهید
هر بار که محتوای یک بیت‌مپ را تغییر می‌دهید، دفعه‌ی بعد که آن را رسم می‌کنید، دوباره به عنوان یک بافت GPU آپلود می‌شود.
با احتیاط از آلفا استفاده کنید
وقتی با استفاده از setAlpha ، AlphaAnimation یا ObjectAnimator یک نما را شفاف می‌کنید، در یک بافر خارج از صفحه رندر می‌شود که نرخ پر شدن مورد نیاز را دو برابر می‌کند. هنگام اعمال آلفا در نماهای بسیار بزرگ، تنظیم نوع لایه نما را روی LAYER_TYPE_HARDWARE در نظر بگیرید.