Android 3.0 (API düzeyi 11) sürümünden itibaren, Android 2D oluşturma ardışık düzeni donanımı destekler
ivme, yani bir test üzerinde gerçekleştirilen tüm çizim işlemleri
View
adlı kullanıcının kanvası GPU'yu kullanıyor. Bu özelliği etkinleştirmek için gereken kaynakların artması
uygulamanız daha fazla RAM kullanır.
Hedef API düzeyiniz >=14 ise donanım hızlandırma varsayılan olarak etkindir. Ancak bunu
etkinleştirilmelidir. Uygulamanız yalnızca standart görünümler ve
Drawable
durumunda ise bu özelliğin genel olarak etkinleştirilmesi ters çizime neden olmaz.
hoşuma gidiyor. Ancak tüm 2D çizimlerde donanım hızlandırma desteklenmediğinden
işlemleri için etkinleştirildiğinde, özel görünümlerinizden veya çizim çağrılarınızdan bazılarını etkileyebilir. Sorunlar
kendilerini genellikle görünmez öğeler, istisnalar veya yanlış oluşturulmuş pikseller olarak gösterir. Alıcı:
telafi etmek için, Android size donanım hızlandırmayı birden fazla cihazda etkinleştirme veya devre dışı bırakma
seviyelere dokunun. Donanım hızlandırmayı denetleme başlıklı makaleyi inceleyin.
Uygulamanız özel çizim yapıyorsa uygulamanızı gerçek donanım cihazlarında test edin bulun. Çizim işlemleri için destek bölümünde, donanım hızlandırma ve bunların nasıl çözüleceği.
Ayrıca Çerçeve API'leriyle OpenGL başlıklı makaleyi de inceleyin ve Renderscript
Donanım hızlandırmayı denetleme
Donanım hızlandırmayı aşağıdaki düzeylerde denetleyebilirsiniz:
- Başvuru
- Etkinlik
- Pencere
- Göster
Uygulama düzeyi
Android manifest dosyanızda, aşağıdaki özelliği
Tüm cihazınız için donanım hızlandırmayı etkinleştirmek üzere <application>
uygulama:
<application android:hardwareAccelerated="true" ...>
Etkinlik düzeyi
Genel olarak donanım hızlandırma etkinken uygulamanız düzgün çalışmıyorsa
bu seçeneği, bireysel etkinlikler için de kontrol edebiliyorsunuz. Şu adresten donanım hızlandırmayı etkinleştirmek veya devre dışı bırakmak için:
kullanıyorsanız android:hardwareAccelerated
özelliğini kullanarak
<activity>
öğesi. Aşağıdaki örnekte, mobil cihazlar için donanım hızlandırmayı
uygulamanın tamamını ancak bir etkinlik için devre dışı bırakırsa:
<application android:hardwareAccelerated="true"> <activity ... /> <activity android:hardwareAccelerated="false" /> </application>
Pencere düzeyi
Daha da hassas denetime ihtiyacınız olursa belirli bir alan için donanım hızlandırmayı penceresinde bulunur:
Kotlin
window.setFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED )
Java
getWindow().setFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
Not: Şu anda donanım hızlandırmayı pencere seviyesinde
Görünüm düzeyi
Çalışma zamanında tek bir görünüm için donanım hızlandırmayı şu kodu kullanabilirsiniz:
Kotlin
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
Java
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
Not: Şu anda aşağıdaki adresten donanım hızlandırmayı etkinleştiremezsiniz: görünüm düzeyiyle belirlenir. Görünüm katmanlarının, donanım hızlandırmayı devre dışı bırakma dışında başka işlevleri de vardır. Kullanımları hakkında daha fazla bilgi için Katmanları görüntüleme konusuna bakın.
Bir görünümün donanım hızlandırmalı olup olmadığını belirleme
Bazen bir uygulamanın, şu anda donanım üzerinde çalışan özellikle de özel görünümler gibi metrikler için hızlandırılmıştır. Bu, özellikle çok sayıda özel çizim yaptığından, yeni çizim uygulaması tarafından yapılan tüm işlemler ardışık düzeni oluşturur.
Uygulamanın donanım hızlandırmalı olup olmadığını kontrol etmenin iki farklı yolu vardır:
View.isHardwareAccelerated()
karşılığında iadeView
, donanım ivmeli bir ağa bağlı isetrue
penceresini kapatın.Canvas.isHardwareAccelerated()
.Canvas
donanım hızlandırmalıysatrue
değerini döndürür
Bu kontrolü çizim kodunuzda yapmanız gerekiyorsa
Bunun yerine Canvas.isHardwareAccelerated()
Mümkün olduğunda View.isHardwareAccelerated()
. Bir görüntüleme
bir donanım hızlandırmalı pencereye bağlandığında, yine de donanım
olmayan bir pencere kullanılarak çizilebilir.
hızlandırılmış Canvas. Bu durum, örneğin, önbelleğe alma için bir bit eşlem üzerinde görünüm çizerken yaşanır
amaçlar.
Android çizim modelleri
Donanım hızlandırma etkinleştirildiğinde Android çerçevesi farklı bir çizim modeli kullanır. uygulamanızı ekranda oluşturmak için görüntüleme listelerini kullanır. Tam olarak anlamak için uygulamanızı nasıl etkileyebileceğini öğrendiğinize göre, Android'in donanım hızlandırma olmadan da görünümler çizer. Aşağıdaki bölümlerde, yazılım tabanlı ve donanım hızlandırmalı çizim modelleridir.
Yazılım tabanlı çizim modeli
Yazılım çizim modelinde görünümler aşağıdaki iki adımla çizilir:
- Hiyerarşiyi geçersiz kıl
- Hiyerarşiyi çizme
Bir uygulamanın, kullanıcı arayüzünün bir bölümünü güncellemesi gerektiğinde, değişen herhangi bir görünümde invalidate()
yöntemini (veya varyantlarından birini) çağırır
içerik. Geçersiz kılma mesajları, hesaplama işlemi için görünüm hiyerarşisinin en üstüne
ekranın yeniden çizilmesi gereken bölgelerine (kirli bölge) girin. Ardından Android sistemi,
hiyerarşide kirli bölgeyle kesişen herhangi bir görünüm çizer. Maalesef
iki dezavantajı vardır:
- Öncelikle, bu model her çizim işleminde çok fazla kod yürütmeyi gerektirir. Örneğin,
uygulamanız bir düğmede
invalidate()
çağırıyor ve düğmesi başka bir görünümün üstünde duruyorsa, Android sistemi değiştirildi. - İkinci sorun, çizim modelinin uygulamanızdaki hataları gizleyebilmesidir.
Android sistemi, kirli bölgeyle kesişen görüntülemeleri yeniden çizer.
invalidate()
değiştirilmemiş olsa bile değiştirilmiş olanlar yeniden çizilebilir karar verdim. Bu durumda, ikinci bir görünüm elde etmek için başka bir görünümün geçersiz doğru davranışa yol açabilir. Bu davranış, uygulamanızda her değişiklik yaptığınızda değişebilir. Bunun nedeni: Özel üzerinde her zamaninvalidate()
ile iletişime geçmelisiniz. görüntüleyebilirsiniz.
Not: Android görünümlerinde (ör. arka plan) özellikleri değiştiğinde invalidate()
otomatik olarak çağrılacaktır
TextView
içindeki metni seçin.
Donanım hızlandırmalı çizim modeli
Android sistemi, ekran güncellemesi istemek ve görünüm oluşturmak için invalidate()
ve draw()
kullanmaya devam eder, ancak
farklı olabilir. Çizim komutlarını hemen yürütmek yerine, Android
sistem, bunları görünüm hiyerarşisinin çıkışını içeren görüntü listelerine kaydeder.
anlamına gelir. Diğer bir optimizasyon da Android sisteminin yalnızca kayıt ve güncelleme yapmasıdır.
invalidate()
ile kirli olarak işaretlenen görüntülemelerin listelerini gösterir
çağrısına bir tıklama URL'si eklemeniz gerekir. Geçersiz kılınmamış görünümler, daha önce yeniden çizilerek yeniden çizilebilir.
kaydedilen ekran gösterilir. Yeni çizim modeli üç aşamadan oluşur:
- Hiyerarşiyi geçersiz kıl
- Görüntü listelerini kaydetme ve güncelleme
- Ekran listelerini çizin
Bu modelde, draw()
yönteminin yürütülmesi için kirli bölgeyle kesişen bir görünümden yararlanamazsınız. Android sisteminin bir
görünümünün görüntüleme listesindeyse invalidate()
yöntemini çağırmanız gerekir. Unutma
bunu yapmak, görünümün değiştirildikten sonra bile aynı görünmesine neden olur.
Görüntüleme listelerini kullanmak animasyon performansının da faydasını sağlar çünkü belirli özellikler ayarlanır,
Örneğin, alfa veya rotasyon gibi, hedeflenen görünümün geçersiz kılınmasını gerektirmez (
otomatik olarak) sağlar. Bu optimizasyon, görüntüleme listesi içeren görünümler için de (reklamlarınızın
için hızlandırılmıştır.) Örneğin, Button
değerinin üzerinde ListView
içeren bir LinearLayout
olduğunu varsayalım. LinearLayout
için görüntüleme listesi şöyle görünüyor
bu:
- DrawDisplayList(ListView)
- DrawDisplayList(Düğme)
Şimdi ListView
öğesinin opaklığını değiştirmek istediğinizi varsayalım. Şu tarihten sonra:
ListView
cihazında setAlpha(0.5f)
çağrılıyor, görüntüleme listesi şimdi gösteriliyor
şunu içerir:
- SaveKatmanAlpha(0,5)
- DrawDisplayList(ListView)
- Geri yükle
- DrawDisplayList(Düğme)
ListView
öğesinin karmaşık çizim kodu yürütülmedi. Bunun yerine
sistem yalnızca çok daha basit olan LinearLayout
öğelerinin görüntüleme listesini güncelledi. İçinde
etkinleştirilmiş olmayan bir uygulama için, hem listenin hem de
tekrar yürütülür.
Çizim işlemleri desteği
Donanım hızlandığında, 2D oluşturma ardışık düzeni en yaygın olarak kullanılan
Canvas
çizim işlemlerinin yanı sıra daha az kullanılan çok sayıda işlem. Tüm
Android ile birlikte gelen uygulamaları oluşturmak için kullanılan çizim işlemleri, varsayılan widget'lar
ve yansıma ve karolara ayrılmış dokular gibi yaygın olarak kullanılan gelişmiş görsel efektler,
desteklenir.
Aşağıdaki tabloda, API düzeylerinde çeşitli işlemlerin destek düzeyi açıklanmaktadır:
Desteklenen ilk API düzeyi | ||||
Tuval | ||||
PaintBitmapMesh() (renk dizisi) | 18 | |||
PaintPicture() | 23 | |||
drawPosText() | 16 | |||
PaintTextOnPath() | 16 | |||
drawVertices() | 29 | |||
setDrawFilter() | 16 | |||
klipYolu() | 18 | |||
klipBölge() | 18 | |||
klipRect(Bölge.Op.XOR) | 18 | |||
klipRect(Bölge.Op.Farkı) | 18 | |||
klipRect(Bölge.Op.Tersine Fark) | 18 | |||
Döndürme/perspektif ile klipRect() | 18 | |||
Boyama yapın | ||||
setAntiAlias() (metin için) | 18 | |||
setAntiAlias() (satırlar için) | 16 | |||
setFilterBitmap() | 17 | |||
setDoğrusalText() | ✗ | |||
setMaskFilter() | ✗ | |||
setPathEffect() (satırlar için) | 28 | |||
setShadowKatman() (metin dışında) | 28 | |||
setStrokeCap() (satırlar için) | 18 | |||
setStrokeCap() (puanlar için) | 19 | |||
setSubpixelText() | 28 | |||
Xfermode | ||||
PorterDuff.Mode.DARKEN (çerçeve arabelleği) | 28 | |||
PorterDuff.Mode.LIGHTEN (framebuffer) | 28 | |||
PorterDuff.Mode.OVERLAY (çerçeve arabelleği) | 28 | |||
Gölgelendirici | ||||
ComposeShader'daki ComposeShader'ı | 28 | |||
ComposeShader içinde aynı tür gölgelendiriciler | 28 | |||
ComposeShader'daki yerel matris | 18 |
Tuval ölçeklendirme
Donanım hızlandırmalı 2D oluşturma ardışık düzeni, öncelikle ölçeklendirilmemiş çizimi desteklemek için derlenmiştir. Bazı çizim işlemleri daha yüksek ölçek değerlerinde kaliteyi önemli ölçüde düşürüyor. Bu işlemleri, 1.0 ölçeğinde çizilen ve GPU tarafından dönüştürülen dokular şeklinde uygulanır. API'de başlatılıyor tüm çizim işlemleri sorunsuz şekilde ölçeklenebilir.
Aşağıdaki tabloda, uygulamanın büyük ölçekleri doğru şekilde işlemek için ne zaman değiştirildiği gösterilmektedir:Ölçeklendirilecek çizim işlemi | Desteklenen ilk API düzeyi |
PaintText() | 18 |
drawPosText() | 28 |
PaintTextOnPath() | 28 |
Basit Şekiller* | 17 |
Karmaşık Şekiller* | 28 |
PaintPath() | 28 |
Gölge katmanı | 28 |
Not: "Basit" şekiller drawRect()
,
drawCircle()
, drawOval()
, drawRoundRect()
ve
drawArc()
(useCenter=false ile) içermeyen bir Boya ile yayınlanan komutlar
PathEffect'tir ve varsayılan olmayan birleştirmeler içermez (setStrokeJoin()
/
setStrokeMiter()
) seçin. Bu çizim komutlarının diğer örnekleri "Karmaşık" inç
yukarıdaki tabloya bakın.
Uygulamanız bu eksik özelliklerden veya sınırlamalardan herhangi birinden etkileniyorsa
uygulamanızın yalnızca etkilenen bölümü için donanım hızlandırmasını
setLayerType(View.LAYER_TYPE_SOFTWARE, null)
Bu sayede projenizin
diğer her yerde donanım hızlandırmadan yararlanmaya devam edebilirsiniz. Etkinleştirme hakkında daha fazla bilgi için Donanım hızlandırmayı denetleme başlıklı makaleye bakın.
ve uygulamanızda farklı düzeylerde donanım hızlandırmayı devre dışı bırakın.
Katmanları görüntüleme
Android'in tüm sürümlerinde, görünümler ekran dışı arabelleklerde oluşturulabiliyordu.
veya Canvas.saveLayer()
kullanarak bir görünümün çizim önbelleğini kullanabilirsiniz. Ekran dışındaki arabelleklerin veya katmanların çeşitli kullanım alanları vardır. Bu araçları ekiple paylaşılan
daha iyi performans elde edebilir. Örneğin,
Bir görünümü geçici olarak oluşturmak için Canvas.saveLayer()
kullanarak solma efektlerini uygulayabilirsiniz
sonra bir opaklık faktörüyle tekrar ekranda birleştiriyoruz.
Android 3.0 (API düzeyi 11) sürümünden itibaren, katmanların nasıl ve ne zaman kullanılacağı konusunda daha fazla kontrole sahip olursunuz.
View.setLayerType()
yöntemiyle deneyin. Bu API iki
parametreler: kullanmak istediğiniz katmanın türü ve isteğe bağlı Paint
katmanın nasıl birleştirilmesi gerektiğini açıklayan nesnedir. Bir öğeye renk filtreleri, özel karıştırma modları veya opaklık uygulamak için Paint
parametresini kullanabilirsiniz.
katmanıdır. Bir görünümde üç katman türünden biri kullanılabilir:
LAYER_TYPE_NONE
: Görünüm normal şekilde oluşturulur ve desteklenmez ekran dışı bir arabellek tarafından yapılır. Bu, varsayılan davranıştır.LAYER_TYPE_HARDWARE
: Görünüm, donanımda aşağıdaki gibi oluşturulur: uygulama, donanım hızlandırmalıysa donanım dokusunu kullanır. Uygulama, donanım değilse bu katman türüLAYER_TYPE_SOFTWARE
ile aynı şekilde davranır.LAYER_TYPE_SOFTWARE
: Görünüm, yazılım biçiminde bit eşlem.
Kullandığınız katmanın türü hedefinize bağlıdır:
- Performans: Görünümü donanıma dönüştürmek için donanım katmanı türü kullanın
dokunun. Bir görünüm bir katmana dönüştürüldükten sonra, çizim kodunun yürütülmesi gerekmez
görünüm
invalidate()
çağırana kadar. Örneğin, Böylece, alfa animasyonları doğrudan katmana uygulanabilir. tam ekran görüntüsü olduğunu hissediyorum. - Görsel efektler: Görünümlere özel görsel işlemler uygulamak için bir donanım veya yazılım katmanı türü ve
Paint
kullanın. Örneğin herkesinColorMatrixColorFilter
kullanarak siyah beyaz bir görünüm çizin. - Uyumluluk: Bir görünümün oluşturulmasını zorunlu kılmak için yazılım katmanı türü kullanın daha fazla bilgi edineceksiniz. Donanım hızlandırmalı bir görünüm (örneğin, donanım hızlandırmalıysa), oluşturma sorunları yaşıyorsa bu, çalışmanın kolay bir yoludur sorunları çözmek için ardışık düzendir.
Katmanları ve animasyonları görüntüleme
Donanım katmanları, uygulamanız sırasında daha hızlı ve daha akıcı animasyonlar sunabilir
donanım hızlandırmalı bir yöntemdir. Saniyede 60 kare hızında bir animasyon çalıştırmak
çok sayıda çizim işlemi yapan karmaşık görünümlere
animasyon oluşturmaktır. Bu durum,
hedef kitlenize nasıl
görünümü donanım dokusuna dönüştürmek için donanım katmanlarını kullanma. Donanım dokusu,
daha sonra görünümü canlandırmak için kullanılır. Böylece, görünümün kendini sürekli olarak yeniden çizme ihtiyacını ortadan kaldırır.
dikkat edin. Görünümü değiştirmediğiniz sürece görünüm yeniden çizilmez
özelliklerini (invalidate()
) çağıran ya da invalidate()
öğesini manuel olarak çağıran özellikler. İçinde bir animasyon çalıştırdığınızda
ve istediğiniz sorunsuz sonuçları alamazsanız, şurada donanım katmanlarını etkinleştirmeyi düşünün:
elde edebilirsiniz.
Bir görünüm bir donanım katmanı tarafından desteklendiğinde, bazı özellikleri katman ekranda birleştirilir. Bu özellikleri ayarlamak, görünümün geçersiz kılınmasını ve yeniden çizilmesini gerektirir. Aşağıdaki özellik listesi, katman birleştirilir. Bu özelliklerden herhangi biri için belirleyicinin çağrılması, Hedeflenen görünümü geçersiz kılma ve yeniden çizilmemesi:
alpha
: Katmanın opaklığını değiştirirx
,y
,translationX
,translationY
: Katmanın konumunu değiştirirscaleX
,scaleY
: Katmanın boyutunu değiştirirrotation
,rotationX
,rotationY
: katmanın 3D uzaydaki yönüpivotX
,pivotY
: Katmanın dönüşüm kaynağını değiştirir
Bu özellikler, ObjectAnimator
ile bir görünüm canlandırırken kullanılan adlardır. Bu mülklere erişmek istiyorsanız
belirleyicidir. Örneğin, alfa özelliğini değiştirmek için setAlpha()
yöntemini çağırın. Aşağıdaki kod snippet'i, en verimli şekilde
bir görünümü Y ekseni etrafında 3D olarak döndürmek için:
Kotlin
view.setLayerType(View.LAYER_TYPE_HARDWARE, null) ObjectAnimator.ofFloat(view, "rotationY", 180f).start()
Java
view.setLayerType(View.LAYER_TYPE_HARDWARE, null); ObjectAnimator.ofFloat(view, "rotationY", 180).start();
Donanım katmanları video belleği kullandığı için bunları etkinleştirmeniz önemle tavsiye edilir. yalnızca animasyon süresi boyunca kullanabilir ve animasyon bittikten sonra bunları devre dışı bırakabilirsiniz. Siz animasyon işleyicileri kullanarak bunu yapabilirsiniz:
Kotlin
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() }
Java
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();
Mülk animasyonu hakkında daha fazla bilgi için Mülk animasyonu konusuna bakın.
İpuçları ve püf noktaları
Donanım hızlandırmalı 2D grafiğe geçmek performansı anında artırabilir, ancak yine de aşağıdaki adımları izleyerek uygulamanızı GPU'yu etkili bir şekilde kullanacak şekilde tasarlamanız gerekir: öneriler:
- Uygulamanızdaki görüntüleme sayısını azaltma
- Sistemin görüntüleme sayısı ne kadar fazlaysa sistem de o kadar yavaş olacaktır. Bu, yazılımın ardışık düzeni oluşturabilirsiniz. Görüntüleme sayısını azaltmak, kullanıcı arayüzünüzü optimize etmenin en kolay yollarından biridir.
- Fazla çizimden kaçınma
- Birbirinin üzerine çok fazla katman çizmeyin. Kaybolan tüm görünümleri yarı saydam görünümlerle örtüler. Üste karıştırılmış birkaç katman çizmeniz gerekiyorsa bunları tek bir katmanda birleştirmeyi düşünün. Mevcut iş ortağı ile ilgili ekranda kare başına piksel sayısının 2,5 katından fazla çizim yapmaması gerekir (bir bit eşlem sayısındaki şeffaf pikseller!).
- Çizim yöntemlerinde oluşturma nesneleri oluşturma
- Bir oluşturma yöntemi her çağrıldığında yeni bir
Paint
veya yeni birPath
oluşturmak, sık yapılan bir hatadır. Bu da çöpe atılan daha sık çalışmasını ve donanımdaki önbellekleri ve optimizasyonları atlar ardışık düzendir. - Şekilleri çok sık değiştirmeyin
- Örneğin karmaşık şekiller, yollar ve daireler, doku maskeleri kullanılarak oluşturulur. Hepsini Bir yol oluşturduğunuzda veya değiştirdiğinizde donanım ardışık düzeni, Pahalı.
- Bit eşlemleri çok sık değiştirmeyin
- Bir bit eşlemin içeriğini her değiştirdiğinizde, bit eşlemin GPU dokusu olarak tekrar yüklenir. bir dahaki sefere çizin.
- Alfa sürümünü dikkatli kullanın
setAlpha()
kullanarak bir görünümü yarı saydam yaptığınızda,AlphaAnimation
veyaObjectAnimator
, o değeri, gerekli doluluk oranını iki katına çıkaran bir ekran dışı arabellekte oluşturulur. Alfa uygulanırken çok büyük görünümlerde, görünümün katman türünüLAYER_TYPE_HARDWARE