Penggunaan radio nirkabel untuk mentransfer data berpotensi menjadi salah satu sumber konsumsi daya baterai paling signifikan pada aplikasi Anda. Untuk meminimalkan konsumsi daya baterai akibat aktivitas jaringan, Anda perlu memahami pengaruh model konektivitas Anda pada hardware radio yang mendasarinya.
Tutorial ini memperkenalkan Anda dengan mesin status radio nirkabel dan menjelaskan cara model konektivitas aplikasi Anda berinteraksi dengannya. Tutorial tersebut juga membahas cara meminimalkan koneksi data, penggunaan pengambilan data, dan pemaketan transfer untuk meminimalkan konsumsi daya baterai akibat transfer data.
Mesin status radio
Radio nirkabel yang sepenuhnya aktif mengonsumsi daya yang signifikan, sehingga radio dapat beralih dari satu status energi ke status lainnya untuk menghemat daya saat tidak digunakan, sekaligus berupaya meminimalkan latensi yang terkait dengan "penyalaan" radio saat diperlukan.
Mesin status untuk radio jaringan 3G standar terdiri dari tiga status energi:
Daya penuh: Digunakan saat koneksi aktif, memungkinkan perangkat mentransfer data pada tingkat tertinggi yang dimungkinkan.
Daya rendah: Status antara, menggunakan sekitar 50% daya baterai dalam keadaan penuh.
Siaga: Status energi minimal saat tidak ada koneksi jaringan yang aktif atau saat koneksi jaringan tidak diperlukan.
Meskipun mengonsumsi daya baterai jauh lebih sedikit, status rendah dan siaga juga menimbulkan latensi yang signifikan terhadap permintaan jaringan. Diperlukan waktu sekitar 1,5 detik untuk mengembalikan status energi dari daya rendah ke daya penuh, dan lebih dari 2 detik dari siaga ke daya penuh.
Untuk meminimalkan latensi, mesin status menerapkan penundaan untuk menunda transisi ke status energi yang lebih rendah. Gambar 1 menggunakan pengaturan waktu AT&T untuk radio 3G standar.
Gambar 1. Mesin status radio nirkabel 3G standar.
Mesin status radio pada setiap perangkat, terutama penundaan transisi ("waktu akhir") dan latensi pengaktifan yang terkait, akan bervariasi bergantung pada teknologi radio nirkabel yang digunakan (2G, 3G, LTE, dll.) serta ditentukan dan dikonfigurasi oleh jaringan operator tempat perangkat beroperasi.
Tutorial ini menjelaskan mesin status representatif untuk radio nirkabel 3G standar, berdasarkan data yang diberikan oleh AT&T. Namun, prinsip umum dan praktik terbaik yang dihasilkan berlaku untuk semua implementasi radio nirkabel.
Pendekatan ini sangat efektif untuk penjelajahan web standar karena mencegah latensi yang tidak diinginkan saat pengguna menjelajahi web. Waktu akhir yang relatif rendah juga memastikan bahwa begitu sesi penjelajahan selesai, radio dapat beralih ke status energi yang lebih rendah.
Sayangnya, pendekatan ini dapat mengakibatkan aplikasi yang tidak efisien pada OS smartphone modern seperti Android, di mana aplikasi berjalan di latar depan (latensi penting) dan juga di latar belakang (masa pakai baterai harus diprioritaskan).
Cara aplikasi memengaruhi mesin status radio
Setiap kali Anda membuat koneksi jaringan baru, radio beralih ke status daya penuh. Dalam kasus mesin status radio 3G standar yang dijelaskan di atas, radio akan tetap berada dalam kondisi daya penuh sepanjang durasi transfer—plus tambahan waktu akhir 5 detik—diikuti 12 detik pada status energi rendah. Jadi, untuk perangkat 3G standar, setiap sesi transfer data akan menyebabkan radio mengonsumsi energi selama hampir 20 detik.
Dalam praktiknya, hal ini berarti aplikasi yang mentransfer data tidak terpaket selama 1 detik setiap 18 detik akan membuat radio nirkabel aktif terus-menerus, dan baru mengalihkannya ke daya tinggi saat radio hendak memasuki mode siaga. Akibatnya, setiap menit radio akan mengonsumsi daya baterai pada status daya tinggi selama 18 detik, dan pada status daya rendah selama 42 detik sisanya.
Sebagai perbandingan, aplikasi yang sama yang mentransfer data terpaket selama 3 detik setiap menit akan membuat radio tetap berada dalam status daya tinggi selama 8 detik saja, dan akan bertahan dalam status daya rendah selama 12 detik setelahnya.
Contoh kedua ini memungkinkan radio untuk berada dalam status siaga selama 40 detik setiap menitnya, sehingga menghasilkan pengurangan signifikan dalam konsumsi daya baterai.
Gambar 2. Perbandingan penggunaan daya radio nirkabel untuk transfer data terpaket vs tidak terpaket.
Mengambil data
Pengambilan data adalah cara efektif untuk mengurangi jumlah sesi transfer data independen. Dengan pengambilan data, Anda dapat mendownload semua data yang kemungkinan akan Anda perlukan selama jangka waktu tertentu dalam sekali burst, melalui satu koneksi, pada kapasitas penuh.
Dengan memuat transfer di awal, Anda mengurangi jumlah aktivasi radio yang diperlukan untuk mendownload data. Hasilnya, Anda tidak hanya menghemat masa pakai baterai, tetapi juga mengurangi latensi, menurunkan bandwidth yang diperlukan, dan mengurangi waktu download.
Pengambilan data juga memberikan pengalaman pengguna yang lebih baik dengan meminimalkan latensi dalam aplikasi yang disebabkan oleh menunggu selesainya proses download, sebelum melakukan suatu tindakan atau menampilkan data.
Namun, jika digunakan terlalu agresif, pengambilan data memunculkan risiko berupa meningkatnya konsumsi daya baterai dan penggunaan bandwidth—serta kuota download—dengan mendownload data yang tidak digunakan. Anda juga harus memastikan bahwa pengambilan data tidak menunda pengaktifan aplikasi selagi aplikasi tersebut menunggu pengambilan data selesai. Dalam praktiknya, hal itu dapat berarti data akan diproses secara progresif, atau inisiasi transfer berurutan diprioritaskan sedemikian rupa sehingga data yang diperlukan untuk pengaktifan aplikasi didownload dan diproses terlebih dahulu.
Seberapa agresif Anda mengambil data bergantung pada ukuran data yang didownload dan kemungkinan penggunaan data tersebut. Sebagai gambaran kasarnya, berdasarkan mesin status yang dijelaskan di atas, untuk data yang memiliki kemungkinan digunakan 50% dalam sesi pengguna saat ini, biasanya Anda dapat mengambil data selama sekitar 6 detik (sekitar 1-2 Mb) sebelum potensi biaya dari mendownload data yang tidak digunakan dapat mengimbangi potensi penghematan dari tidak mendownload data tersebut.
Secara umum, sebaiknya ambil data sedemikian rupa sehingga Anda hanya perlu memulai download baru setiap 2 hingga 5 menit, dan dalam urutan 1 hingga 5 megabyte.
Dengan mengikuti prinsip ini, download berukuran besar, seperti file video, sebaiknya dilakukan sebagai potongan-potongan dalam interval yang teratur (setiap 2 hingga 5 menit), sehingga secara efektif Anda hanya mengambil data video yang kemungkinan akan ditonton dalam beberapa menit berikutnya.
Perlu diperhatikan bahwa download selanjutnya harus dipaketkan, seperti yang dijelaskan di bagian Membuat batch transfer dan koneksi, dan bahwa perkiraan ini akan bervariasi menurut jenis dan kecepatan koneksi, seperti yang dibahas dalam Mengubah pola download berdasarkan jenis konektivitas.
Mari kita lihat beberapa contoh praktis berikut:
Pemutar musik
Anda dapat memilih untuk mengambil data seluruh album, tetapi jika pengguna berhenti mendengarkan setelah lagu pertama, berarti Anda telah membuang banyak bandwidth dan masa pakai baterai.
Pendekatan yang lebih baik adalah mempertahankan buffer satu lagu selain lagu yang sedang diputar. Untuk streaming musik, daripada mempertahankan streaming berkelanjutan yang membuat radio tetap aktif sepanjang waktu, cobalah menggunakan HTTP live streaming untuk mentransmisikan streaming audio dalam beberapa burst, serupa dengan pendekatan pengambilan data yang dijelaskan di atas.
Pembaca berita
Banyak aplikasi berita berupaya mengurangi penggunaan bandwidth dengan hanya mendownload judul setelah suatu kategori dipilih, artikel lengkap setelah pengguna memilih untuk membacanya, dan thumbnail tepat saat mereka men-scroll tampilan.
Dengan pendekatan ini, radio akan dipaksa untuk tetap aktif sepanjang sebagian besar sesi membaca pengguna, selama mereka men-scroll judul, berpindah kategori, dan membaca artikel. Selain itu, peralihan terus-menerus antara beberapa status energi akan mengakibatkan latensi signifikan saat pengguna beralih kategori atau membaca artikel.
Pendekatan yang lebih baik adalah mengambil sejumlah data yang wajar pada saat pengaktifan, lalu memulai dengan menampilkan sekumpulan judul dan thumbnail berita—memastikan latensi selama pengaktifan tetap rendah—dan melanjutkan dengan judul dan thumbnail sisanya, serta teks artikel untuk setiap artikel yang tersedia dari setidaknya daftar judul utama.
Alternatif lainnya adalah mengambil data setiap judul, thumbnail, teks artikel, dan bahkan mungkin gambar artikel lengkap—biasanya di latar belakang pada jadwal yang telah ditentukan. Pendekatan ini berisiko menghabiskan bandwidth dan masa pakai baterai secara signifikan untuk mendownload konten yang tidak benar-benar digunakan, sehingga sebaiknya diimplementasikan dengan hati-hati.
Salah satu solusinya adalah menjadwalkan agar download lengkap hanya berjalan saat perangkat terhubung ke Wi-Fi, dan mungkin hanya saat daya perangkat sedang diisi. Hal ini dibahas lebih mendetail dalam Mengubah pola download berdasarkan jenis konektivitas.
Membuat batch transfer dan koneksi
Setiap kali Anda memulai koneksi—berapa pun ukuran transfer data yang terkait—Anda berpotensi membuat radio mengonsumsi daya selama hampir 20 detik saat menggunakan radio nirkabel 3G standar.
Aplikasi yang mem-ping server setiap 20 detik, hanya untuk mengonfirmasi bahwa aplikasi sedang berjalan dan terlihat oleh pengguna, akan membuat radio tetap aktif tanpa batas waktu, yang menyebabkan biaya baterai yang signifikan untuk transfer data yang sebenarnya hampir tidak ada.
Di sinilah pentingnya memaketkan transfer data dan membuat antrean untuk transfer yang tertunda. Jika dilakukan dengan benar, Anda dapat secara efektif memindahkan beberapa transfer yang akan terjadi ke dalam rentang waktu yang sama sehingga semuanya ditransfer bersamaan. Hal ini untuk memastikan bahwa radio mengonsumsi daya untuk durasi sesingkat mungkin.
Filosofi yang mendasari pendekatan ini adalah mentransfer sebanyak mungkin data pada setiap sesi transfer untuk membatasi jumlah sesi yang diperlukan.
Hal itu berarti Anda perlu membuat batch transfer dengan membuat antrean transfer yang dapat menoleransi keterlambatan, dan menghentikan update dan pengambilan data terjadwal, sehingga operasi ini dijalankan saat transfer yang sensitif waktu diperlukan. Demikian pula, update terjadwal dan pengambilan data rutin harus mulai menjalankan antrean transfer yang tertunda.
Untuk contoh praktis, mari kita lihat kembali contoh sebelumnya dari Mengambil data.
Misalkan aplikasi berita yang menggunakan rutinitas pengambilan data yang dijelaskan di atas. Aplikasi pembaca berita mengumpulkan informasi analisis untuk memahami pola membaca pengguna dan mengurutkan artikel yang paling populer. Agar berita tetap baru, aplikasi memeriksa ketersediaan update setiap jam. Untuk menghemat bandwidth, bukannya mendownload foto lengkap untuk setiap artikel, aplikasi hanya mengambil data thumbnail dan mendownload foto lengkap hanya jika foto dipilih.
Dalam contoh ini, semua informasi analisis yang terkumpul dalam aplikasi harus dipaketkan bersama dan diantrekan untuk didownload, bukannya dikirim begitu terkumpul. Paket yang dihasilkan sebaiknya ditransfer saat foto berukuran penuh sedang didownload, atau saat update per jam sedang dilakukan.
Semua transfer yang sensitif waktu atau sesuai permintaan—seperti mendownload gambar berukuran penuh—akan menghentikan update terjadwal secara rutin. Update terencana ini sebaiknya dijalankan bersamaan dengan transfer berdasarkan permintaan, dengan update berikutnya dijadwalkan terjadi setelah interval yang ditetapkan. Pendekatan ini dapat mengurangi biaya yang timbul dari melakukan update rutin dengan membonceng pada download foto sensitif waktu yang diperlukan.
Mengurangi koneksi
Secara umum, menggunakan kembali koneksi jaringan yang ada akan lebih efisien daripada memulai koneksi baru. Penggunaan kembali koneksi juga memungkinkan jaringan bereaksi lebih efektif terhadap kongesti dan masalah data jaringan terkait.
Daripada membuat beberapa koneksi simultan untuk mendownload data, atau merangkai beberapa permintaan GET yang berurutan, sebaiknya Anda memaketkan permintaan tersebut menjadi GET tunggal, jika memungkinkan.
Misalnya, membuat satu permintaan akan lebih efisien untuk setiap artikel berita yang akan ditampilkan dalam satu permintaan/respons daripada membuat beberapa kueri untuk beberapa kategori berita. Radio nirkabel harus berada dalam status aktif agar dapat mengirimkan paket penghentian/konfirmasi penghentian yang terkait dengan waktu tunggu server dan klien. Karena itu, sebaiknya tutup koneksi saat tidak sedang digunakan daripada menunggu hingga waktu tunggunya habis.
Meskipun begitu, menutup koneksi terlalu dini dapat mencegahnya digunakan kembali, sehingga kemudian diperlukan overhead tambahan untuk membuat koneksi baru. Kompromi yang baik adalah tidak menutup koneksi dengan seketika, melainkan menutupnya sebelum waktu tunggunya habis.
Mengidentifikasi masalah dengan Network Profiler
Gunakan Network Profiler untuk melacak kapan aplikasi Anda membuat permintaan jaringan. Anda dapat memantau bagaimana dan kapan aplikasi Anda mentransfer data dan mengoptimalkan kode yang mendasarinya dengan tepat.
Gambar 3 menunjukkan pola transfer sejumlah kecil data dalam selang sekitar 15 detik, yang menunjukkan bahwa efisiensi dapat ditingkatkan secara dramatis dengan mengambil data setiap permintaan atau memaketkan upload.
Gambar 3. Melacak penggunaan jaringan.
Dengan memantau frekuensi transfer data Anda, dan jumlah data yang ditransfer selama setiap koneksi, Anda dapat mengidentifikasi area di aplikasi yang dapat dibuat lebih hemat baterai. Secara umum, Anda perlu mencari lonjakan singkat yang dapat ditunda, atau yang dapat menyebabkan transfer selanjutnya terhenti.
Agar dapat mengidentifikasi penyebab lonjakan transfer dengan lebih baik, Traffic Stats API memungkinkan Anda memberi tag pada transfer data yang terjadi dalam thread menggunakan metode TrafficStats.setThreadStatsTag()
, yang diikuti dengan memberikan tag dan menghapus tag pada setiap soket secara manual menggunakan TrafficStats.tagSocket()
dan TrafficStats.untagSocket()
.
Contoh:
Kotlin
TrafficStats.setThreadStatsTag(0xF00D) TrafficStats.tagSocket(outputSocket) // Transfer data using socket TrafficStats.untagSocket(outputSocket)
Java
TrafficStats.setThreadStatsTag(0xF00D); TrafficStats.tagSocket(outputSocket); // Transfer data using socket TrafficStats.untagSocket(outputSocket);
Library HttpURLConnection
akan otomatis memberikan tag pada soket berdasarkan nilai TrafficStats.getThreadStatsTag()
saat ini. Library ini juga akan memberikan tag dan menghapus tag pada soket saat digunakan kembali melalui kumpulan keep-alive.
Kotlin
class IdentifyTransferSpikeTask { @WorkerThread fun request(url: String) { TrafficStats.setThreadStatsTag(0xF00D) // Make network request using HttpURLConnection.connect() ... TrafficStats.clearThreadStatsTag(); } }
Java
public class IdentifyTransferSpikeTask { @WorkerThread public void request(String url) { TrafficStats.setThreadStatsTag(0xF00D); // Make network request using HttpURLConnection.connect() ... TrafficStats.clearThreadStatsTag(); } }
Pemberian tag pada soket didukung di Android 4.0, tetapi statistik real-time hanya akan ditampilkan pada perangkat yang menjalankan versi Android 4.0.3 atau yang lebih tinggi.