Android için hızlı yinelemeli geliştirme
Bu sayfada, bazel mobile-install
'nın Android için yinelemeli geliştirmeyi nasıl çok daha hızlı hale getirdiği açıklanmaktadır. Bu yaklaşımın avantajları ile ayrı derleme ve yükleme adımlarının dezavantajları açıklanmaktadır.
Özet
Android uygulamasında küçük değişiklikleri çok hızlı bir şekilde yüklemek için aşağıdakileri yapın:
- Yüklemek istediğiniz uygulamanın
android_binary
kuralını bulun. - Cihazınızı
adb
'a bağlayın. - Koşu
bazel mobile-install :your_target
. Uygulama başlatma işlemi normalden biraz daha yavaş olacaktır. - Kodu veya Android kaynaklarını düzenleyin.
- Koşu
bazel mobile-install :your_target
. - Hızlı ve minimum artımlı yüklemenin keyfini çıkarın.
Bazel'e iletilebilecek ve işinize yarayabilecek bazı komut satırı seçenekleri:
--adb
, Bazel'a hangi adb ikili dosyasının kullanılacağını bildirir.--adb_arg
,adb
komut satırına ek bağımsız değişkenler eklemek için kullanılabilir. Bu özelliğin faydalı bir uygulaması, iş istasyonunuza bağlı birden fazla cihazınız varsa hangi cihaza yüklemek istediğinizi seçmektir:bazel mobile-install :your_target -- --adb_arg=-s --adb_arg=<SERIAL>
Emin değilseniz örneğe göz atın, Google Grupları'nda bizimle iletişime geçin veya GitHub'da sorun bildirin.
Giriş
Geliştiricinin araç zincirinin en önemli özelliklerinden biri hızdır: Kodu değiştirip bir saniye içinde çalışırken görmek ile değişikliklerinizin beklentilerinizi karşılayıp karşılamadığına dair geri bildirim almadan önce dakikalarca, hatta bazen saatlerce beklemeniz arasında çok büyük bir fark vardır.
Maalesef .apk oluşturmak için geleneksel Android araç zinciri, birçok monolitik ve sıralı adım içerir. Android uygulaması oluşturmak için bu adımların tamamının uygulanması gerekir. Google'da, Google Haritalar gibi daha büyük projelerde tek satırlık bir değişikliği oluşturmak için beş dakika beklemek alışılmadık bir durum değildi.
bazel mobile-install
, değişiklikleri budama, işi parçalama ve Android'in iç yapısını akıllıca değiştirme yöntemlerini kullanarak Android'de yinelemeli geliştirmeyi çok daha hızlı hale getirir. Tüm bunları, uygulamanızın kodunda herhangi bir değişiklik yapmadan gerçekleştirir.
Geleneksel uygulama yükleme ile ilgili sorunlar
Android uygulaması oluşturmayla ilgili bazı sorunlar vardır. Örneğin:
Dexing. Varsayılan olarak, Dexer aracı (geçmişte
dx
, şimdid8
veyar8
) derlemede tam olarak bir kez çağrılır ve önceki derlemelerdeki çalışmayı nasıl yeniden kullanacağını bilmez: Yalnızca bir yöntem değiştirilmiş olsa bile her yöntemi tekrar dex'e dönüştürür.Cihaza veri yükleme. adb, USB 2.0 bağlantısının tam bant genişliğini kullanmaz ve daha büyük uygulamaların yüklenmesi uzun zaman alabilir. Yalnızca küçük bölümler değişmiş olsa bile (ör. bir kaynak veya tek bir yöntem) uygulamanın tamamı yüklendiğinden bu durum büyük bir performans sorununa yol açabilir.
Yerel koda derleme. Android L, uygulamaları Dalvik gibi tam zamanında derlemek yerine önceden derleyen yeni bir Android çalışma zamanı olan ART'yi tanıttı. Bu, uygulamaların çok daha hızlı çalışmasını sağlar ancak yükleme süresi uzar. Kullanıcılar genellikle bir uygulamayı bir kez yükleyip birçok kez kullandıkları için bu durum onlar açısından iyi bir denge noktasıdır. Ancak bir uygulamanın birçok kez yüklendiği ve her sürümün en fazla birkaç kez çalıştırıldığı durumlarda geliştirme süreci yavaşlar.
bazel mobile-install
yaklaşımı
bazel mobile-install
aşağıdaki iyileştirmeleri yapar:
Parçalanmış şekersizleştirme ve dexleme. Bazel, uygulamanın Java kodunu oluşturduktan sonra sınıf dosyalarını yaklaşık olarak eşit boyutlu parçalara ayırır ve
d8
'yı bunlar üzerinde ayrı ayrı çağırır.d8
, son derlemeden bu yana değişmeyen parçalarda çağrılmaz. Bu parçalar daha sonra ayrı parçalı APK'lar halinde derlenir.Artımlı dosya aktarımı. Android kaynakları, .dex dosyaları ve yerel kitaplıklar ana .apk'dan kaldırılır ve ayrı bir mobil yükleme dizininde saklanır. Bu sayede, kod ve Android kaynakları, uygulamanın tamamı yeniden yüklenmeden bağımsız olarak güncellenebilir. Böylece, dosyaların aktarılması daha az zaman alır ve yalnızca değişen .dex dosyaları cihazda yeniden derlenir.
Parçalanmış yükleme. Mobil yükleme, bağlı cihazdaki parçalanmış APK'ları birleştirmek ve tutarlı bir deneyim sağlamak için Android Studio'nun
apkdeployer
aracını kullanır.
Parçalı Dexing
Parçalanmış dexing oldukça basittir: .jar dosyaları oluşturulduktan sonra bir araç bunları yaklaşık olarak eşit boyuttaki ayrı .jar dosyalarına böler ve ardından önceki derlemeden bu yana değiştirilenler üzerinde d8
'ı çağırır. Hangi parçaların dex'e dönüştürüleceğini belirleyen mantık Android'e özgü değildir. Yalnızca Bazel'in genel değişiklik temizleme algoritmasını kullanır.
Parçalama algoritmasının ilk sürümü, .class dosyalarını alfabetik olarak sıralayıp listeyi eşit boyutlu parçalara bölüyordu. Ancak bu yaklaşımın ideal olmadığı anlaşıldı: Bir sınıf eklendiğinde veya kaldırıldığında (iç içe yerleştirilmiş ya da anonim bir sınıf olsa bile) alfabetik olarak sonraki tüm sınıflar bir sıra kayıyor ve bu da parçaların yeniden dexlenmesine neden oluyordu. Bu nedenle, ayrı sınıflar yerine Java paketlerinin parçalanmasına karar verildi. Elbette bu durumda yeni bir paket eklenir veya kaldırılırsa yine birçok parça dizine eklenir ancak bu durum, tek bir sınıfın eklenmesi veya kaldırılmasına kıyasla çok daha az görülür.
Parça sayısı, --define=num_dex_shards=N
işareti kullanılarak komut satırı yapılandırmasıyla kontrol edilir. İdeal bir dünyada Bazel, kaç parçanın en iyi olacağını otomatik olarak belirlerdi. Ancak Bazel şu anda herhangi birini yürütmeden önce işlem kümesini (örneğin, derleme sırasında yürütülecek komutlar) bilmelidir. Bu nedenle, uygulamada sonunda kaç Java sınıfı olacağını bilmediği için optimum parça sayısını belirleyemez. Genel olarak, parça sayısı ne kadar fazla olursa derleme ve yükleme o kadar hızlı olur ancak dinamik bağlayıcı daha fazla iş yapmak zorunda kalacağından uygulama başlatma işlemi yavaşlar. İdeal nokta genellikle 10 ile 50 parça arasındadır.
Aşamalı dağıtım
Artımlı APK parçası aktarımı ve yüklemesi artık "Mobil yükleme yaklaşımı" bölümünde açıklanan apkdeployer
yardımcı programı tarafından gerçekleştiriliyor.
Mobil yüklemenin önceki (yerel) sürümlerinde ilk yüklemelerin manuel olarak izlenmesi ve sonraki yüklemelerde --incremental
işaretinin seçici olarak uygulanması gerekirken rules_android
'deki en son sürüm büyük ölçüde basitleştirilmiştir. Uygulamanın kaç kez yüklendiği veya yeniden yüklendiğinden bağımsız olarak aynı mobil yükleme çağrısı kullanılabilir.
apkdeployer
aracı, genel olarak çeşitli adb
alt komutlarını kapsar. Ana giriş noktası mantığı, com.android.tools.deployer.Deployer
sınıfında bulunabilir. Diğer yardımcı sınıflar da aynı pakette yer alır.
Deployer
sınıfı, diğer şeylerin yanı sıra, APK'ları bölmek için bir yol listesi ve yükleme hakkında bilgi içeren bir protobuf alır. Ayrıca, yükleme oturumu oluşturmak ve uygulama bölümlerini artımlı olarak dağıtmak için Android App Bundle'lara yönelik dağıtım özelliklerinden yararlanır.
Uygulama ayrıntıları için ApkPreInstaller
ve ApkInstaller
sınıflarına bakın.
Sonuçlar
Performans
Genel olarak, bazel mobile-install
, küçük bir değişiklikten sonra büyük uygulamaların oluşturulması ve yüklenmesinde 4 ila 10 kat hızlanma sağlar.
Aşağıdaki sayılar, birkaç Google ürünü için hesaplanmıştır:
Bu süre, değişikliğin niteliğine bağlıdır. Örneğin, temel bir kitaplık değiştirildikten sonra yeniden derleme daha uzun sürer.
Sınırlamalar
Sahte uygulamanın kullandığı yöntemler her durumda işe yaramaz. Aşağıdaki durumlarda bant genişliği beklendiği gibi çalışmaz:
Mobil yükleme yalnızca
rules_android
Starlark kuralları aracılığıyla desteklenir. Daha ayrıntılı bilgi için "Mobil yüklemenin kısa geçmişi" bölümüne bakın.Yalnızca ART çalıştıran cihazlar desteklenir. Mobil yükleme, yalnızca Dalvik'te değil, ART çalıştıran cihazlarda bulunan API ve çalışma zamanı özelliklerini kullanır. Android L'den (API 21+) daha yeni herhangi bir Android çalışma zamanı uyumlu olmalıdır.
Bazel'in kendisi, 17 veya daha yeni bir sürümün Java çalışma zamanı ve dil sürümüyle çalıştırılmalıdır.
8.4.0'dan önceki Bazel sürümlerinde mobile-install için bazı ek işaretler belirtilmelidir. Bazel Android eğitimine göz atın. Bu işaretler, Bazel'e Starlark mobile-install yönünün nerede olduğunu ve hangi kuralların desteklendiğini bildirir.
Mobil uygulama yükleme reklamlarının kısa tarihi
Daha önceki Bazel sürümleri, C++, Java ve Android gibi popüler diller ve ekosistemler için yerleşik derleme ve test kurallarını doğrudan içeriyordu. Bu nedenle, bu kurallara yerel kurallar deniyordu. Bazel 8 (2024'te yayınlandı), bu kuralların çoğu Starlark diline taşındığı için bu kurallar için desteği kaldırdı. Daha fazla bilgi için "Bazel 8.0 LTS blog yayınını" inceleyin.
Eski yerel Android kuralları, mobil yükleme işlevinin eski bir yerel sürümünü de destekliyordu. Bu özellik artık "mobil yükleme v1" veya "doğal mobil yükleme" olarak adlandırılıyor. Bu işlev, Bazel 8'de yerleşik Android kurallarıyla birlikte silindi.
Artık tüm mobil yükleme işlevlerinin yanı sıra tüm Android derleme ve test kuralları Starlark'ta uygulanıyor ve rules_android
GitHub deposunda yer alıyor. En son sürüm "mobil yükleme v3" veya "MIv3" olarak bilinir.
Adlandırmayla ilgili not: Bir zamanlar Google'da yalnızca dahili olarak kullanılabilen bir "mobile-install v2" vardı ancak bu sürüm hiçbir zaman harici olarak yayınlanmadı ve hem Google'ın dahili hem de OSS kuralları_android dağıtımı için yalnızca v3 kullanılmaya devam ediyor.