getApplicationContext()
hampir selalu salah. Ms. Hackborn (antara lain) sangat eksplisit bahwa Anda hanya menggunakan getApplicationContext()
ketika Anda tahu mengapa Anda menggunakan getApplicationContext()
dan hanya ketika Anda perlu menggunakannya getApplicationContext()
.
Terus terang, "beberapa programmer" menggunakan getApplicationContext()
(atau getBaseContext()
, pada tingkat lebih rendah) karena pengalaman Java mereka terbatas. Mereka menerapkan kelas batin (misalnya, OnClickListener
untuk Button
dalam Activity
) dan perlu a Context
. Alih-alih menggunakan MyActivity.this
untuk mendapatkan di kelas luar ' this
, mereka menggunakan getApplicationContext()
atau getBaseContext()
untuk mendapatkan Context
objek.
Anda hanya menggunakan getApplicationContext()
ketika Anda tahu Anda membutuhkan Context
untuk sesuatu yang mungkin hidup lebih lama daripada kemungkinan lain yang Context
Anda miliki. Skenario meliputi:
Gunakan getApplicationContext()
jika Anda membutuhkan sesuatu yang terkait dengan Context
itu sendiri akan memiliki ruang lingkup global. Saya menggunakan getApplicationContext()
, misalnya, dalam WakefulIntentService
, untuk statis yang WakeLock
akan digunakan untuk layanan ini. Karena itu WakeLock
statis, dan saya perlu Context
untuk mendapatkan PowerManager
untuk menciptakannya, itu paling aman untuk digunakan getApplicationContext()
.
Gunakan getApplicationContext()
ketika Anda mengikat ke Service
dari Activity
, jika Anda ingin melewati ServiceConnection
(yaitu, pegangan ke ikatan) antara Activity
instance via onRetainNonConfigurationInstance()
. Android secara internal melacak binding melalui ini ServiceConnections
dan memegang referensi ke Contexts
yang membuat binding. Jika Anda mengikat dari Activity
, maka Activity
instance baru akan memiliki referensi ServiceConnection
yang memiliki referensi implisit ke yang lama Activity
, dan yang lama Activity
tidak dapat dikumpulkan sampah.
Beberapa pengembang menggunakan subkelas khusus Application
untuk data global mereka sendiri, yang mereka ambil via getApplicationContext()
. Itu tentu saja mungkin. Saya lebih suka anggota data statis, jika tanpa alasan lain Anda hanya dapat memiliki satuApplication
objek kustom . Saya membangun satu aplikasi menggunakan Application
objek kustom dan merasa sangat menyakitkan. Ibu Hackborn juga setuju dengan posisi ini .
Berikut adalah alasan mengapa tidak digunakan di getApplicationContext()
mana pun Anda pergi:
Itu tidak lengkap Context
, mendukung semua yang Activity
dilakukannya. Berbagai hal yang akan Anda coba lakukan Context
akan gagal, sebagian besar terkait dengan GUI .
Itu dapat membuat kebocoran memori, jika Context
dari getApplicationContext()
memegang sesuatu yang dibuat oleh panggilan Anda di atasnya bahwa Anda tidak membersihkan. Dengan Activity
, jika itu memegang sesuatu, begitu Activity
sampah dikumpulkan, segala sesuatu yang lain akan keluar juga. The Application
objek tetap untuk masa proses Anda.
getApplicationContext()
ketika Anda tahu persis mengapa Anda membutuhkannya dalam situasi tertentu. Menggembungkan tata letak? Gunakan aktivitas. Mengikat ke layanan, di mana Anda memerlukannya untuk bertahan dari perubahan konfigurasi? GunakangetApplicationContext()
, jadi ikatannya tidak terikat denganActivity
instance.Saya pikir ada banyak hal yang kurang didokumentasikan di situs SDK, ini salah satunya. Klaim yang akan saya ajukan adalah sepertinya lebih baik menggunakan konteks aplikasi secara default dan hanya menggunakan konteks aktivitas saat Anda benar-benar perlu. Satu-satunya tempat di mana saya pernah melihat bahwa Anda memerlukan konteks aktivitas adalah untuk dialog kemajuan. SBERG412 mengklaim bahwa Anda harus menggunakan konteks aktivitas untuk pesan bersulang, namun dokumen Android jelas menunjukkan konteks aplikasi yang sedang digunakan. Saya selalu menggunakan konteks aplikasi untuk bersulang karena contoh Google ini. Jika itu salah, maka Google menjatuhkan bola di sini.
Berikut ini lebih banyak untuk dipikirkan dan ditinjau:
Untuk pesan roti panggang, Panduan Pengembang Google menggunakan konteks aplikasi dan secara eksplisit mengatakan untuk menggunakannya: Pemberitahuan Toast
Di bagian dialog panduan Dev, Anda melihat bahwa AlertDialog.Builder menggunakan konteks aplikasi, dan kemudian bilah kemajuan menggunakan konteks aktivitas. Ini tidak dijelaskan oleh Google. Dialog
Sepertinya alasan yang baik untuk menggunakan konteks aplikasi adalah ketika Anda ingin menangani perubahan konfigurasi seperti perubahan orientasi, dan Anda ingin mempertahankan objek yang memerlukan konteks seperti Views. Jika Anda melihat di sini: Run Time Changes Ada peringatan tentang menggunakan konteks aktivitas, yang dapat membuat kebocoran. Ini dapat dihindari dengan konteks aplikasi dengan pandangan yang harus dipertahankan (setidaknya itulah pemahaman saya). Dalam sebuah aplikasi yang saya tulis, saya bermaksud menggunakan konteks aplikasi karena saya mencoba untuk menahan beberapa pandangan dan hal-hal lain pada perubahan orientasi, dan saya masih ingin aktivitas dihancurkan dan diciptakan kembali pada perubahan orientasi. Jadi saya harus menggunakan konteks aplikasi untuk tidak menyebabkan kebocoran memori (lihat Menghindari Kebocoran memori). Bagi saya sepertinya ada banyak alasan bagus untuk menggunakan konteks aplikasi alih-alih konteks aktivitas, dan bagi saya sepertinya Anda akan lebih sering menggunakannya daripada konteks aktivitas. Itulah yang tampaknya dilakukan oleh banyak buku Android, dan itulah yang dilakukan oleh banyak contoh Google.
Dokumentasi Google benar-benar membuatnya tampak seperti menggunakan konteks aplikasi baik-baik saja dalam kebanyakan kasus, dan pada kenyataannya muncul lebih sering daripada menggunakan konteks aktivitas dalam contoh mereka (setidaknya contoh yang saya lihat). Jika benar-benar masalah untuk menggunakan konteks aplikasi, maka Google benar-benar perlu lebih menekankan hal ini. Mereka perlu menjelaskan, dan mereka perlu mengulang beberapa contoh mereka. Saya tidak akan menyalahkan ini sepenuhnya pada pengembang yang tidak berpengalaman karena otoritas (Google) benar-benar membuatnya tampak seperti itu bukan masalah untuk menggunakan konteks aplikasi.
sumber
Saya menggunakan tabel ini sebagai panduan kapan harus menggunakan berbagai jenis Konteks seperti konteks Aplikasi (yaitu:)
getApplicationContext()
dan konteks aktivitas , juga konteks BroadcastReceiver :Semua pahala pergi ke penulis asli di sini untuk info lebih lanjut.
sumber
Ada dua jenis Konteks:
Konteks aplikasi dikaitkan dengan aplikasi dan akan selalu sama sepanjang umur aplikasi - tidak berubah. Jadi jika Anda menggunakan Toast, Anda dapat menggunakan konteks aplikasi atau bahkan konteks aktivitas (keduanya) karena roti panggang dapat ditampilkan dari mana saja dengan aplikasi Anda dan tidak dilampirkan ke jendela tertentu. Tetapi ada banyak pengecualian, satu pengecualian adalah ketika Anda perlu menggunakan atau melewati konteks aktivitas.
Konteks aktivitas dikaitkan dengan aktivitas dan dapat dihancurkan jika aktivitas tersebut dihancurkan - mungkin ada beberapa aktivitas (lebih dari kemungkinan) dengan satu aplikasi. Dan kadang-kadang Anda benar-benar membutuhkan pegangan konteks aktivitas. Misalnya, jika Anda meluncurkan aktivitas baru, Anda perlu menggunakan konteks aktivitas di Intentnya sehingga aktivitas peluncuran baru terhubung ke aktivitas saat ini dalam hal tumpukan aktivitas. Namun, Anda dapat menggunakan konteks aplikasi juga untuk meluncurkan aktivitas baru, tetapi kemudian Anda harus menetapkan flag
Intent.FLAG_ACTIVITY_NEW_TASK
untuk memperlakukannya sebagai tugas baru.Mari kita pertimbangkan beberapa kasus:
MainActivity.this
merujuk ke konteks MainActivity yang memperluas kelas Activity tetapi kelas dasar (activity) juga memperluas kelas Context, sehingga dapat digunakan untuk menawarkan konteks aktivitas.getBaseContext()
menawarkan konteks aktivitas.getApplication()
menawarkan konteks aplikasi.getApplicationContext()
juga menawarkan konteks aplikasi.Untuk informasi lebih lanjut silakan periksa tautan ini .
sumber
downloadmanager
, dan ketika sinyal selesai diterima, itu akan menampilkan dialog misalnya "Apa yang ingin Anda lakukan dengan unduhan ini?". Solusi (peretasan) saya menyimpan yang terbaruActivity
distatic
Application
kelas, dan meminta yang terbaruActivity
saat unduhan selesai. Namun, saya ragu ini adalah implementasi yang tepat. TL; DR Bagaimana cara menampilkan AlertDialog di mana saja di aplikasi?Saya bertanya-tanya mengapa tidak menggunakan Konteks Aplikasi untuk setiap operasi yang didukungnya. Pada akhirnya itu menurunkan kemungkinan kebocoran memori dan tidak ada pemeriksaan nol untuk getContext () atau getActivity () (saat menggunakan konteks aplikasi yang diinjeksi atau diperoleh melalui metode statis dari Aplikasi). Pernyataan, seperti yang dibuat oleh Ms. Hackborn untuk menggunakan Konteks Aplikasi hanya jika diperlukan, sepertinya tidak meyakinkan bagi saya tanpa penjelasan mengapa. Tetapi tampaknya saya telah menemukan alasan yang tidak patut untuk dipikirkan:
Karena itu tidak dijamin bahwa semua operasi yang digambarkan didukung oleh Konteks Aplikasi pada tabel di bawah ini akan berfungsi pada semua perangkat Android!
sumber
Dua contoh hebat tentang kapan Anda harus menggunakan konteks Aktivitas vs. konteks Aplikasi adalah ketika menampilkan pesan Toast atau pesan Dialog bawaan ketika menggunakan konteks Aplikasi akan menyebabkan pengecualian:
atau
Kedua hal ini memerlukan informasi dari konteks Aktivitas yang tidak disediakan dalam konteks Aplikasi.
sumber
Konteks aplikasi hidup sampai aplikasi Anda hanya hidup dan itu tidak tergantung pada Siklus Hidup Aktivitas tetapi, konteks menjaga objek berumur panjang . Jika objek yang Anda gunakan sementara, waktu itu menggunakan Konteks Aplikasi dan Konteks Aktivitas digunakan sama sekali berlawanan dengan Konteks Aplikasi.
sumber