instal seluler bazel

Laporkan masalah Lihat sumber Per Malam · 7,2 · 7,1 · 7,0 · 6,5 · 6,4

Pengembangan iteratif yang cepat untuk Android

Halaman ini menjelaskan cara bazel mobile-install membuat pengembangan berulang untuk Android dengan jauh lebih cepat. Menjelaskan manfaat pendekatan ini dibandingkan tantangan metode pemasangan aplikasi tradisional.

Ringkasan

Untuk menginstal perubahan kecil ke aplikasi Android dengan sangat cepat, lakukan hal berikut:

  1. Temukan aturan android_binary untuk aplikasi yang ingin Anda instal.
  2. Nonaktifkan Proguard dengan menghapus atribut proguard_specs.
  3. Tetapkan atribut multidex ke native.
  4. Tetapkan atribut dex_shards ke 10.
  5. Sambungkan perangkat Anda yang menjalankan ART (bukan Dalvik) melalui USB dan aktifkan USB melakukan proses debug padanya.
  6. Jalankan bazel mobile-install :your_target. {i>App startup<i} akan sedikit lebih lambat dari biasanya.
  7. Edit kode atau resource Android.
  8. Jalankan bazel mobile-install --incremental :your_target.
  9. Nikmati tanpa perlu menunggu banyak.

Beberapa opsi command line untuk Bazel yang mungkin berguna:

  • --adb memberi tahu Bazel biner adb mana yang akan digunakan
  • --adb_arg dapat digunakan untuk menambahkan argumen tambahan ke command line adb. Salah satu aplikasi yang berguna dari hal ini adalah memilih perangkat mana yang ingin Anda instal jika Anda memiliki beberapa perangkat yang terhubung ke workstation: bazel mobile-install --adb_arg=-s --adb_arg=<SERIAL> :your_target
  • --start_app otomatis memulai aplikasi

Jika ragu, lihat contoh atau hubungi kami.

Pengantar

Salah satu atribut terpenting dari toolchain developer adalah kecepatan: ada adalah perbedaan antara mengubah kode dan melihatnya berjalan dalam beberapa menit dan terkadang berjam-jam, sebelum Anda mendapatkan umpan balik pada apakah perubahan yang Anda lakukan sesuai dengan yang Anda harapkan.

Sayangnya, toolchain Android tradisional untuk membangun .apk memerlukan banyak langkah monolitik, berurutan dan semua ini harus dilakukan untuk membuat aplikasi Android. Di Google, menunggu lima menit untuk membuat satu baris perubahan yang biasa terjadi pada proyek yang lebih besar seperti Google Maps.

bazel mobile-install membuat pengembangan iteratif untuk Android jauh lebih cepat dengan menggunakan kombinasi pemangkasan perubahan, sharding pekerjaan, dan manipulasi cerdas Internal Android, semuanya tanpa mengubah kode aplikasi Anda.

Masalah pada penginstalan aplikasi tradisional

Membangun aplikasi Android memiliki beberapa masalah, termasuk:

  • Dexing. Secara default, "dx" dipanggil sekali saja dalam build dan mengetahui cara menggunakan kembali pekerjaan dari build sebelumnya: ia melakukan dexes setiap metode lagi, bahkan meskipun hanya satu metode yang diubah.

  • Mengupload data ke perangkat. adb tidak menggunakan bandwidth penuh USB 2.0 koneksi internet, dan aplikasi yang lebih besar dapat memakan banyak waktu. Seluruh aplikasi diupload, meskipun hanya sebagian kecil yang berubah, misalnya, aset atau metode tunggal, sehingga ini bisa menjadi bottleneck utama.

  • Kompilasi ke kode native. Android L memperkenalkan ART, sebuah runtime Android baru, yang mengompilasi aplikasi terlebih dahulu alih-alih mengompilasinya tepat waktu seperti Dalvik. Hal ini membuat aplikasi jauh lebih cepat dengan biaya penginstalan yang lebih lama baik. Ini adalah kompromi yang baik bagi pengguna karena mereka biasanya menginstal aplikasi sekali dan menggunakannya berkali-kali, namun mengakibatkan pengembangan menjadi lebih lambat di mana aplikasi diinstal berkali-kali dan setiap versi dijalankan paling sering beberapa kali.

Pendekatan bazel mobile-install

bazel mobile-installmembuat peningkatan berikut:

  • dexing yang di-sharding. Setelah mem-build kode Java aplikasi, Bazel melakukan sharding class menjadi bagian yang berukuran kira-kira sama dan memanggil dx secara terpisah di mereka. dx tidak dipanggil pada shard yang tidak berubah sejak build terakhir.

  • Transfer file inkremental. Resource Android, file .dex, dan native library akan dihapus dari .apk utama dan disimpan di direktori pemasangan seluler. Hal ini memungkinkan update kode dan Android sumber daya secara independen tanpa menginstal ulang seluruh aplikasi. Dengan demikian, mentransfer file membutuhkan lebih sedikit waktu dan hanya file .dex yang memiliki diubah dikompilasi ulang di perangkat.

  • Memuat bagian aplikasi dari luar .apk. Sebuah aplikasi stub kecil dimasukkan ke dalam .apk yang memuat resource Android, kode Java, dan kode native dari direktori penginstalan seluler di perangkat, lalu mentransfer kontrol ke aplikasi yang sebenarnya. Semua ini transparan untuk aplikasi, kecuali dalam beberapa kasus sudut yang dijelaskan di bawah.

Dexing dengan Shard

Sharded dexing sangatlah mudah: setelah file .jar dibuat, alat membaginya menjadi file .jar terpisah yang kira-kira sama ukurannya, lalu memanggil dx pada item yang diubah sejak build sebelumnya. Logika yang menentukan shard mana yang akan di-dex tidak spesifik untuk Android: shard ini hanya menggunakan algoritma pemangkasan perubahan umum Bazel.

Versi pertama algoritma sharding hanya mengurutkan file .class menurut abjad, lalu membagi daftar itu menjadi bagian-bagian yang berukuran sama, tetapi ini terbukti kurang optimal: jika class ditambahkan atau dihapus (bahkan class bertingkat atau anonim satu), hal itu akan menyebabkan semua kelas berdasarkan abjad setelahnya bergeser satu, yang mengakibatkan hasil dexing pada shard tersebut lagi. Karena itu, diputuskan untuk melakukan sharding Java paket, bukan class individual. Tentu saja, ini masih menghasilkan melakukan dexing banyak sharding jika paket baru ditambahkan atau dihapus, tetapi hasilnya jauh lebih sedikit lebih sering dibandingkan menambahkan atau menghapus satu class.

Jumlah shard dikontrol oleh file BUILD (menggunakan android_binary.dex_shards). Dalam kondisi ideal, Bazel akan otomatis menentukan jumlah shard yang terbaik, tetapi Bazel saat ini harus tahu kumpulan tindakan (misalnya, perintah yang akan dieksekusi selama pembangunan) sebelum mengeksekusi salah satunya, sehingga tidak dapat menentukan jumlah shard yang optimal karena tidak mengetahui berapa banyak kelas Java yang akan ada di dalam . Secara umum, semakin banyak shard, semakin cepat build dan instalasi, tetapi startup aplikasi menjadi lebih lambat, karena {i>link <i}harus melakukan lebih banyak pekerjaan. Nilai terbaik biasanya antara 10 dan 50 sharding.

Transfer file inkremental

Setelah membuat aplikasi, langkah berikutnya adalah menginstalnya, sebaiknya dengan upaya yang paling sedikit. Penginstalan terdiri dari langkah-langkah berikut:

  1. Menginstal .apk (biasanya menggunakan adb install)
  2. Mengupload file .dex, resource Android, dan library native ke direktori instal seluler

Tidak banyak inkrementalitas di langkah pertama: aplikasi sudah diinstal atau tidak. Bazel saat ini mengandalkan pengguna untuk menunjukkan apakah ia harus melakukan langkah ini melalui opsi command line --incremental karena tidak dapat menentukan semua kasus jika diperlukan.

Pada langkah kedua, file aplikasi dari build dibandingkan dengan file di perangkat file manifes yang mencantumkan file aplikasi mana yang ada di perangkat dan {i>checksum<i}. Semua file baru diupload ke perangkat, dan semua file yang telah diubah diperbarui, dan setiap file yang telah dihapus akan dihapus dari perangkat seluler. Jika manifes tidak ada, diasumsikan bahwa setiap file perlu dapat diupload.

Perhatikan bahwa mungkin saja menipu algoritma instalasi inkremental dengan mengubah file pada perangkat, tetapi tidak {i>checksum<i} dalam manifes. Hal ini dapat telah diamanatkan dengan menghitung {i>checksum<i} file pada tapi ini dianggap tidak sepadan dengan peningkatan waktu instalasinya.

Aplikasi Stub

Aplikasi rintisan adalah tempat keajaiban untuk memuat dexes, kode native, dan Resource Android dari direktori mobile-install di perangkat terjadi.

Pemuatan sebenarnya diimplementasikan dengan membuat subclass BaseDexClassLoader dan merupakan terdokumentasi dengan cukup baik. Hal ini terjadi sebelum setiap akan dimuat, sehingga kelas aplikasi apa pun yang ada dalam apk dapat yang ditempatkan di direktori mobile-install di perangkat agar dapat diperbarui tanpa adb install.

Hal ini perlu dilakukan sebelum dimuat, sehingga tidak ada class aplikasi yang perlu berada di .apk yang artinya perubahan pada kelas-kelas itu akan memerlukan instal ulang.

Hal ini dilakukan dengan mengganti class Application yang ditentukan di AndroidManifest.xml dengan aplikasi stub. Ini mengontrol kapan aplikasi dimulai, dan menyesuaikan loader class dan pengelola sumber daya dengan tepat pada saat paling awal (konstruktornya) menggunakan Refleksi Java pada internal framework Android.

Hal lain yang dilakukan aplikasi stub adalah menyalin library native diinstal oleh penginstalan seluler ke lokasi lain. Hal ini diperlukan karena penaut dinamis memerlukan bit X untuk ditetapkan pada file, yang tidak mungkin lakukan untuk setiap lokasi yang dapat diakses oleh adb non-root.

Setelah semua ini selesai, aplikasi stub kemudian membuat instance Application yang sebenarnya, mengubah semua referensi ke dirinya sendiri menjadi aplikasi dalam framework Android.

Hasil

Performa

Secara umum, bazel mobile-install menghasilkan percepatan pembangunan sebesar 4x hingga 10x lipat dan menginstal aplikasi besar setelah melakukan perubahan kecil.

Angka berikut telah dihitung untuk beberapa produk Google:

Hal ini, tentu saja, tergantung pada sifat perubahan: kompilasi ulang setelah mengubah pustaka dasar membutuhkan waktu lebih lama.

Batasan

Trik yang dimainkan aplikasi stub mungkin tidak pada semua kasus. Kasus berikut akan menunjukkan area yang tidak berfungsi seperti yang diharapkan:

  • Saat Context ditransmisikan ke class Application di ContentProvider#onCreate(). Metode ini dipanggil selama aplikasi startup sebelum kita sempat mengganti instance Application sehingga ContentProvider akan tetap merujuk ke aplikasi stub bukannya yang asli. Bisa dibilang, ini bukan {i>bug<i} karena Anda tidak seharusnya menurunkan Context seperti ini, tetapi ini sepertinya akan terjadi dalam beberapa aplikasi di Google.

  • Resource yang diinstal oleh bazel mobile-install hanya tersedia dari dalam aplikasi. Jika resource diakses oleh aplikasi lain melalui PackageManager#getApplicationResources(), resource ini akan berasal dari penginstalan non-inkremental terakhir.

  • Perangkat yang tidak menjalankan ART. Sementara aplikasi stub bekerja dengan baik pada Froyo dan setelahnya, Dalvik memiliki {i>bug<i} yang membuatnya berpikir bahwa aplikasi itu salah jika kodenya didistribusikan ke beberapa file .dex dalam contohnya, ketika anotasi Java digunakan dalam spesifik sebelumnya. Selama aplikasi Anda tidak menggelitik bug, aplikasi seharusnya berfungsi dengan Dalvik, juga (perhatikan bahwa dukungan untuk versi Android lama bukanlah fokus)