Apakah ada cara untuk mendapatkan Context
instance saat ini di dalam metode statis?
Saya mencari cara itu karena saya benci menyimpan contoh 'Konteks' setiap kali itu berubah.
android
android-context
Andrea Baccega
sumber
sumber
Context
, maka mungkin ada cara yang lebih baik untuk merancang kode.Jawaban:
Melakukan hal ini:
Dalam file Android Manifest, nyatakan yang berikut ini.
Kemudian tulis kelas:
Sekarang di mana-mana panggilan
MyApplication.getAppContext()
untuk mendapatkan konteks aplikasi Anda secara statis.sumber
static context
variabel ini sebagaivolatile
?Mayoritas aplikasi yang menginginkan metode yang nyaman untuk mendapatkan konteks aplikasi membuat kelas mereka sendiri yang meluas
android.app.Application
.PANDUAN
Anda dapat melakukannya dengan terlebih dahulu membuat kelas di proyek Anda seperti berikut:
Kemudian, di AndroidManifest Anda, Anda harus menentukan nama kelas Anda di tag AndroidManifest.xml:
Anda kemudian dapat mengambil konteks aplikasi dalam metode statis menggunakan yang berikut:
PERINGATAN
Sebelum menambahkan sesuatu seperti di atas ke proyek Anda, Anda harus mempertimbangkan apa yang dikatakan dokumentasi:
REFLEKSI
Ada juga cara lain untuk mendapatkan konteks aplikasi menggunakan refleksi. Refleksi sering dipandang rendah di Android dan saya pribadi berpikir ini tidak boleh digunakan dalam produksi.
Untuk mengambil konteks aplikasi kita harus memanggil metode pada kelas tersembunyi ( ActivityThread ) yang telah tersedia sejak API 1:
Ada satu lagi kelas tersembunyi ( AppGlobals ) yang menyediakan cara untuk mendapatkan konteks aplikasi secara statis. Itu mendapatkan konteks menggunakan
ActivityThread
sehingga benar-benar tidak ada perbedaan antara metode berikut dan yang diposting di atas:Selamat coding!
sumber
Dengan asumsi kita sedang berbicara tentang mendapatkan Konteks Aplikasi, saya menerapkannya seperti yang disarankan oleh @Rohit Ghatol memperluas Aplikasi. Apa yang terjadi kemudian, adalah bahwa tidak ada jaminan bahwa konteks yang diambil sedemikian rupa akan selalu non-nol. Pada saat Anda membutuhkannya, biasanya karena Anda ingin menginisialisasi pembantu, atau mendapatkan sumber daya, Anda tidak dapat menunda waktu; menangani case null tidak akan membantu Anda. Jadi saya mengerti bahwa saya pada dasarnya berjuang melawan arsitektur Android, seperti yang dinyatakan dalam dokumen
dan dijelaskan oleh Dianne Hackborn
Dia juga menyarankan solusi untuk masalah ini:
jadi apa yang saya lakukan adalah menyingkirkan memperpanjang Aplikasi, dan meneruskan konteks langsung ke getInstance () pembantu tunggal, sambil menyimpan referensi ke konteks aplikasi di konstruktor pribadi:
penelepon kemudian akan memberikan konteks lokal kepada penolong:
Jadi, untuk menjawab pertanyaan ini dengan benar: ada cara untuk mengakses Konteks Aplikasi secara statis, tetapi mereka semua harus berkecil hati, dan Anda harus lebih suka meneruskan konteks lokal ke getInstance singleton ().
Bagi siapa pun yang tertarik, Anda dapat membaca versi yang lebih rinci di blog fwd
sumber
getInstance(ctx)
. Anda memiliki akarinstance
tipe GCMyHelper
, yang memiliki bidangmContext
tipe pribadiContext
, yang merujuk konteks aplikasi yang dikumpulkan melalui konteks yang diteruskan kegetInstance()
.instance
tidak pernah diset kedua kalinya, juga tidak dihapus, sehingga GC tidak akan pernah menangkap konteks aplikasi yang dirujuk olehinstance
. Anda tidak membocorkan kegiatan apa pun sehingga IMO biaya rendah.this
diApplication.onCreate()
, yang membuat jawaban yang diterima lebih baik.Tidak, saya kira tidak ada. Sayangnya, Anda mengalami panggilan macet
getApplicationContext()
dariActivity
atau salah satu subclass dariContext
. Juga, ini pertanyaan agak terkait.sumber
Berikut adalah cara tidak berdokumen untuk mendapatkan Aplikasi (yang merupakan Konteks) dari mana saja di utas UI. Itu bergantung pada metode statis tersembunyi
ActivityThread.currentApplication()
. Ini harus bekerja setidaknya di Android 4.x.Perhatikan bahwa mungkin untuk metode ini mengembalikan nol, misalnya ketika Anda memanggil metode di luar utas UI, atau aplikasi tidak terikat pada utas.
Masih lebih baik menggunakan solusi @RohitGhatol jika Anda dapat mengubah kode Aplikasi.
sumber
Tergantung pada apa Anda menggunakan konteks untuk. Saya dapat memikirkan setidaknya satu kelemahan dari metode itu:
Jika Anda mencoba membuat
AlertDialog
denganAlertDialog.Builder
,Application
konteksnya tidak akan berfungsi. Saya percaya Anda perlu konteks untuk saat iniActivity
...sumber
Cara Kotlin :
Nyata:
MyApplication.kt
Anda kemudian dapat mengakses properti melalui
MyApplication.instance
sumber
Jika Anda terbuka untuk menggunakan RoboGuice , Anda dapat menyuntikkan konteksnya ke kelas yang Anda inginkan. Berikut adalah contoh kecil bagaimana melakukannya dengan RoboGuice 2.0 (beta 4 pada saat penulisan ini)
sumber
Saya telah menggunakan ini di beberapa titik:
Ini adalah konteks yang valid yang saya gunakan untuk mendapatkan layanan sistem dan bekerja.
Tapi, saya menggunakannya hanya dalam modifikasi framework / base dan tidak mencobanya di aplikasi Android.
Sebuah peringatan bahwa Anda harus tahu: Ketika mendaftar untuk penerima siaran dengan konteks ini, tidak akan bekerja dan Anda akan mendapatkan:
sumber
Kotlin
dan dapatkan Context like
atau
sumber
Anda dapat menggunakan yang berikut ini:
MainActivity.java:
Kelas lain:
sumber
Jika Anda tidak ingin mengubah file manifes, Anda dapat secara manual menyimpan konteks dalam variabel statis di aktivitas awal Anda:
Dan atur konteks saat aktivitas (atau aktivitas) Anda dimulai:
Catatan: Seperti semua jawaban lain, ini adalah potensi kebocoran memori.
sumber
Saya pikir Anda memerlukan tubuh untuk
getAppContext()
metode ini:sumber
Menurut sumber ini Anda bisa mendapatkan Konteks Anda sendiri dengan memperluas ContextWrapper
JavaDoc untuk ContextWrapper
sumber
Jika Anda karena suatu alasan menginginkan konteks Aplikasi di kelas mana pun, bukan hanya yang memperpanjang aplikasi / aktivitas, mungkin untuk beberapa kelas pabrik atau pembantu. Anda dapat menambahkan singleton berikut ke aplikasi Anda.
kemudian inisialisasi di onCreate dengan kelas aplikasi Anda
gunakan di mana saja dengan menelepon
Saya tidak merekomendasikan pendekatan ini untuk apa pun kecuali konteks aplikasi. Karena dapat menyebabkan kebocoran memori.
sumber
Saya menggunakan variasi pola desain Singleton untuk membantu saya dalam hal ini.
Saya kemudian menelepon
ApplicationContextSingleton.setContext( this );
di saya activity.onCreate () danApplicationContextSingleton.setContext( null );
di onDestroy () ;sumber
Saya baru saja merilis kerangka kerja yang terinspirasi jQuery untuk Android bernama Vapor API yang bertujuan untuk membuat pengembangan aplikasi lebih sederhana.
Kelas
$
fasad pusat mempertahankanWeakReference
(tautan ke posting blog Java yang mengagumkan tentang ini oleh Ethan Nicholas) keActivity
konteks saat ini yang dapat Anda ambil dengan menelepon:A
WeakReference
menyimpan referensi tanpa mencegah pengumpulan sampah merebut kembali objek asli, jadi Anda seharusnya tidak memiliki masalah dengan kebocoran memori.Kelemahannya tentu saja adalah Anda menjalankan risiko yang
$.act()
bisa mengembalikan nol. Saya belum menemukan skenario ini, jadi itu mungkin hanya risiko minimal, layak disebut.Anda juga dapat mengatur konteks secara manual jika Anda tidak menggunakan
VaporActivity
sebagaiActivity
kelas Anda :Juga, banyak kerangka kerja Vapor API menggunakan konteks tersimpan ini secara inheren yang mungkin berarti Anda tidak perlu menyimpannya sama sekali jika Anda memutuskan untuk menggunakan kerangka kerja tersebut. Lihatlah situs untuk informasi lebih lanjut dan sampel.
Saya harap itu membantu :)
sumber
Jawaban Rohit sepertinya benar. Namun, perlu diketahui bahwa "Instant Run" AndroidStudio tergantung pada tidak memiliki
static Context
atribut dalam kode Anda, sejauh yang saya tahu.sumber
di Kotlin, menempatkan Konteks / Konteks Aplikasi di objek pendamping masih menghasilkan peringatan
Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)
atau jika Anda menggunakan sesuatu seperti ini:
Ini hanya menipu serat untuk tidak menemukan kebocoran memori, contoh App masih dapat menghasilkan kebocoran memori, karena kelas Aplikasi dan turunannya adalah sebuah Konteks.
Atau, Anda dapat menggunakan antarmuka fungsional atau properti Fungsional untuk membantu Anda mendapatkan konteks aplikasi Anda.
Cukup buat kelas objek:
atau Anda bisa menggunakannya lebih aman menggunakan jenis nullable:
dan di kelas Aplikasi Anda tambahkan baris ini:
dan di manifes Anda menyatakan nama aplikasi ke
. MyApp
Ketika Anda ingin mendapatkan konteksnya, hubungi:
Semoga ini bisa membantu.
sumber
Coba sesuatu seperti ini
sumber