bazel mobil yükleme

Sorun bildirin Kaynağı göster Gece · 7,4 , 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Android için hızlı iteratif geliştirme

Bu sayfada, bazel mobile-install uygulamasının yinelemeli geliştirmeyi nasıl yaptığı açıklanmaktadır çok daha hızlı sağlıyor. Bu yaklaşımın avantajları ile ve geleneksel uygulama yükleme yönteminin zorlukları üzerine konuştuk.

Özet

Android uygulamasında küçük değişiklikleri çok hızlı bir şekilde yüklemek için aşağıdakileri yapın:

  1. Yüklemek istediğiniz uygulamanın android_binary kuralını bulun.
  2. proguard_specs özelliğini kaldırarak ProGuard'ı devre dışı bırakın.
  3. multidex özelliğini native olarak ayarlayın.
  4. dex_shards özelliğini 10 olarak ayarlayın.
  5. ART (Dalvik değil) çalıştıran cihazınızı USB üzerinden bağlayın ve USB hata ayıklama özelliğini etkinleştirin.
  6. bazel mobile-install :your_target çalıştır. Uygulamanın başlatılması normalden biraz daha yavaş olur.
  7. Kodu veya Android kaynaklarını düzenleyin.
  8. bazel mobile-install --incremental :your_target çalıştır.
  9. Çok fazla beklemek zorunda kalmayın.

Bazel'de yararlı olabilecek bazı komut satırı seçenekleri:

  • --adb, Bazel'e hangi adb ikili programını kullanacağını bildirir
  • --adb_arg, adb komut satırına fazladan bağımsız değişkenler eklemek için kullanılabilir. Bunun yararlı uygulamalarından biri, yüklemek istediğiniz cihazı seçmektir iş istasyonunuza bağlı birden fazla cihazınız varsa aşağıdaki adımları uygulayın: bazel mobile-install --adb_arg=-s --adb_arg=<SERIAL> :your_target
  • --start_app, uygulamayı otomatik olarak başlatır

Şüpheye düştüğünüzde örnek veya bize ulaşın.

Giriş

Bir geliştiricinin araç zincirinin en önemli özelliklerinden biri hızdır: Kodu değiştirmek ve bir saniye içinde çalışmasını görmek ile değişikliklerinizin beklediğiniz sonucu verip vermediğine dair geri bildirim almak için dakikalarca, bazen de saatlerce beklemek arasında dünyalar kadar fark vardır.

Maalesef .apk oluşturmak için kullanılan geleneksel Android araç zinciri, birçok tekil ve sıralı adım içerir. Android uygulaması oluşturmak için bunların hepsinin yapılması gerekir. Google'da, Google Haritalar gibi büyük projelerde tek satırlık bir değişiklik yapmak için beş dakika beklemek alışılmış bir durumdu.

bazel mobile-install, uygulamanızın kodunda herhangi bir değişiklik yapmadan Android için yinelemeli geliştirmeyi çok daha hızlı hale getirmek amacıyla değişiklik budama, iş parçalara ayırma ve Android'in dahili işlevlerini akıllıca değiştirme işlemlerini bir arada kullanır.

Geleneksel uygulama yüklemeyle ilgili sorunlar

Android uygulaması oluştururken aşağıdakiler gibi bazı sorunlar var:

  • Dexing. Varsayılan olarak "dx" çağrıldığı için derlemede tam olarak bir kez çağrılır. önceki derlemelerdeki çalışmaları nasıl yeniden kullanacağınızı bilir: Bu sistem, çalışmalarınızı ancak tek bir yöntem değiştirildi.

  • Verileri cihaza yükleme. adb, USB 2.0 bağlantısının tam bant genişliğini kullanmaz ve büyük uygulamaların yüklenmesi çok uzun sürebilir. Uygulama tamamen küçük kısımları değişmiş olsa bile (örneğin, bir kaynak veya bir bu yüzden büyük bir performans sorunu olabilir.

  • Yerel kod derlemesi. Android L, yeni Android çalışma zamanı olan ART'yi Böylece uygulamaları tam zamanında derlemek yerine önceden derler. Dalvik. Bu da daha uzun yükleme maliyetiyle uygulamaları çok daha hızlı hale getirir gerekir. Kullanıcılar genellikle bir uygulamayı bir kez yükleyip birçok kez kullandığından bu, kullanıcılar açısından iyi bir takastır. Ancak 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çalı dizine ekleme. Bazel, uygulamanın Java kodunu derledikten sonra sınıf dosyalarını yaklaşık olarak eşit büyüklükte parçalara ayırır ve dx'ı bunlarda ayrı ayrı çağırır. dx, son derlemeden bu yana değişmeyen kırıklarda çağrılmaz.

  • Artımlı dosya aktarımı. Android kaynakları, .dex dosyaları ve yerel dosyalar kitaplıklar ana .apk'den kaldırılır ve ayrı bir mobil yükleme dizini. Bu, kodu ve Android'i güncellemeyi mümkün kılar ve kaynakların birbirinden bağımsız olmasını sağlayın. Böylece, dosyaları aktarmak daha az zaman alır ve yalnızca yapılan değişiklikler cihaz üzerinde yeniden derlenir.

  • Uygulamanın bazı bölümlerinin .apk dışından yüklenmesi. .apk dosyasına, cihaz üzerindeki mobil yükleme dizininden Android kaynaklarını, Java kodunu ve yerel kodu yükleyen ve ardından kontrolü asıl uygulamaya aktaran küçük bir stub uygulaması yerleştirilir. Aşağıda açıklanan birkaç özel durum dışında, bu işlemler uygulama için şeffaftır.

Parçalı Dex Oluşturma

Parçalı dex oluşturma işlemi makul ölçüde basittir: .jar dosyaları oluşturulduktan sonra, araç bunları yaklaşık olarak eşit boyutta ayrı .jar dosyalarına ayırır, daha sonra Önceki derlemeden sonra değiştirilenler üzerinde dx. Projenin gidişatını hangi kırıkların Android'e özgü olmadığını belirler, yalnızca genel değişiklik budama algoritmasıdır.

Parçalama algoritmasının ilk sürümü, .class dosyalarını sonra listeyi eşit boyutlarda parçalara böldük, ancak daha büyük bir suboptimal: bir sınıf eklendiyse veya kaldırıldıysa (iç içe yerleştirilmiş veya anonim bir sınıf da dahil olmak üzere) sonra tüm sınıfların alfabetik olarak kaymasına neden olur. bu da kırıkların tekrar çözülmesine neden oluyor. Bu nedenle, sınıflar yerine Java paketlerini bölme kararı alındı. Elbette bu yine de yeni bir paket eklendiğinde veya kaldırıldığında çok sayıda parçayı tek bir sınıf eklenmesine veya çıkarılmasına göre daha sıktır.

Kırık sayısı BUILD dosyası tarafından kontrol edilir ( android_binary.dex_shards özelliği) ekleyebilirsiniz. İdeal bir dünyada Bazel otomatik olarak kaç parçanın en iyi olduğunu belirler, ancak Bazel'in bunu şu anda bilmesi gerekir yapılandırmadan önce bir dizi işlem (örneğin, derleme sırasında yürütülecek komutlar) yürütür, böylece ideal kırık sayısını belirleyemez çünkü eninde sonunda kaç Java sınıfı olacağını uygulamasını indirin. Genelde, ne kadar fazla kırık olursa, derleme o kadar hızlı ve ancak uygulama başlatma işlemi daha yavaş olur. Bunun nedeni, bağlayıcının daha fazla işlem yapması gerekir. En iyi performansı genellikle 10 ila 50 parça arasında elde edersiniz.

Artımlı dosya aktarımı

Uygulamayı oluşturduktan sonraki adım, tercihen mümkün olan en az çabayla. Yükleme işlemi aşağıdaki adımlardan oluşur:

  1. .apk yükleniyor (genellikle adb install kullanılarak)
  2. .dex dosyalarını, Android kaynaklarını ve yerel kitaplıkları mobile-install dizine yükleme

İlk adımda çok fazla artımlılık yoktur: Uygulama yüklüdür hakkında bilgi edindiniz. Bazel şu anda bu adımın gerekli olup olmadığını her durumda belirleyemediği için --incremental komut satırı seçeneği aracılığıyla bu adımı yapıp yapmayacağını kullanıcıya sorar.

İkinci adımda, uygulamanın derlemedeki dosyaları cihaz üzerindeki bir dosyayla karşılaştırılır cihazda hangi uygulama dosyalarının bulunduğunu ve bunların sağlamaları da vardır. Cihaza yüklenen yeni dosyalar, değiştirilen dosyalar güncellenir ve kaldırılan dosyalar olanak tanır. Manifest mevcut değilse her dosyanın yüklenmesi gerektiği varsayılır.

Ek yükleme algoritmasının, artımlı yükleme algoritmasının yanı sıra cihazdaki bir dosyayı değiştirir, ancak manifest'teki sağlama toplamını değiştirmez. Bu durum, cihazdaki dosyaların sağlama toplamının hesaplanması yoluyla önlenebilirdi ancak bu işlemin yükleme süresini uzatacağı düşünülerek bu yöntemden vazgeçildi.

Stub uygulaması

Stub uygulaması, dex'leri, yerel kodları ve öğeleri Cihaz üzerindeki mobile-install dizinindeki Android kaynakları gerçekleşir.

Asıl yükleme, BaseDexClassLoader alt sınıfıyla uygulanır ve bir ortaya koymuş olabilir. Bu işlem, uygulamanın sınıflarından herhangi biri yüklenmeden önce gerçekleşir. Böylece, apk'da bulunan uygulama sınıfları cihaz üzerindeki mobile-install dizinine yerleştirilebilir ve adb install olmadan güncellenebilir.

Bu işlemin, uygulamanın sınıfları yüklendiğinden, .apk biçiminde yapılır. Bu da bu sınıflarda yapılan değişikliklerin yeniden yükleyin.

Bu, AndroidManifest.xml içinde belirtilen Application sınıfının stub uygulama ile değiştirilmesiyle yapılır. Bu sınıf, uygulama başlatılırken kontrolü ele alır ve Android çerçevesinin iç kısımlarında Java yansımasını kullanarak sınıf yükleyiciyi ve kaynak yöneticisini en erken anda (yapıcısı) uygun şekilde değiştirir.

Rıdvan uygulamanın yaptığı bir diğer işlem de mobil yükleme tarafından yüklenen yerel kitaplıkları başka bir konuma kopyalamasıdır. Bu gereklidir çünkü dinamik bağlayıcının dosyalarda X bitinin ayarlanmasını gerektirir ve bu kök olmayan bir adb tarafından erişilebilen herhangi bir konum için yapmanız gerekir.

Tüm bunlar yapıldıktan sonra saplama uygulaması, gerçek Application sınıfı; tüm referansları gerçek haliyle değiştirerek bir uygulamadır.

Sonuçlar

Performans

Genel olarak, bazel mobile-install ile inşaat hızı 4 ila 10 kat artırılır sonra küçük bir değişiklikten sonra büyük uygulamalar yüklemeyi ümit ediyoruz.

Aşağıdaki sayılar birkaç Google ürünü için hesaplandı:

Bu, elbette değişikliğin yapısına bağlı: temel kitaplığı değiştirmek daha fazla zaman alır.

Sınırlamalar

Saplama uygulamasında yapılan hileler her durumda işe yaramaz. Aşağıdaki durumlarda, işlevin beklendiği gibi çalışmadığı durumlar vurgulanır:

  • Context, Application sınıfına yayınlandığında ContentProvider#onCreate(). Bu yöntem, uygulama sırasında çağrılır Application örneğini değiştirme fırsatımız olmadan startup'ı sınıfını kullanır. Bu nedenle, ContentProvider, saplama uygulamasına başvurmaya devam eder. e-posta alırsınız. Muhtemelen bu bir hata değildir çünkü Context uygulamasını bu şekilde eski sürüme geçirmem gerekiyordu ancak bu işlemi birkaç dakika içinde yapacağım bazı yöntemleri dinlediniz.

  • bazel mobile-install tarafından yüklenen kaynaklara yalnızca şunun içinden erişilebilir: görebilirsiniz. Diğer uygulamalar kaynaklara PackageManager#getApplicationResources(), bu kaynaklar artımlı olmayan son yükleme.

  • ART çalışmayan cihazlar. Stub uygulaması Froyo ve sonraki sürümlerde iyi çalışırken Dalvik'te, Java ek açıklamaları belirli bir şekilde kullanıldığında olduğu gibi, belirli durumlarda kodu birden fazla .dex dosyasına dağıtılırsa uygulamanın yanlış olduğunu düşünmesine neden olan bir hata vardır. Uygulamanız bu hataları gidermediği sürece Dalvik, (ancak eski Android sürümlerini desteklemenin tam olarak bizim için tam olarak odak)