Saya memiliki layar splash pada pengatur waktu. Masalah saya adalah bahwa sebelum finish()
saya melakukan aktivitas, saya perlu memeriksa bahwa aktivitas berikutnya telah dimulai karena kotak dialog sistem muncul dan saya hanya ingin finish()
; setelah pengguna memilih opsi dari kotak dialog?
Saya tahu bahwa ada banyak pertanyaan tentang bagaimana melihat apakah aktivitas Anda berada di latar depan, tetapi saya tidak tahu apakah ini juga memungkinkan adanya kotak dialog di atas aktivitas.
Inilah masalahnya, warna merah adalah aktivitas saya yang ada di latar belakang sementara dialog berada di latar depan:
EDIT: Saya telah mencoba hanya untuk tidak menggunakan finish()
tetapi kemudian aktivitas saya dapat kembali ke tumpukan aplikasi yang saya coba hindari.
Jawaban:
Inilah yang direkomendasikan sebagai solusi yang tepat :
Dalam
finish()
metode Anda, Anda ingin menggunakanisActivityVisible()
untuk memeriksa apakah aktivitas terlihat atau tidak. Di sana Anda juga dapat memeriksa apakah pengguna telah memilih opsi atau tidak. Lanjutkan saat kedua kondisi terpenuhi.Sumber tersebut juga menyebutkan dua solusi yang salah ... jadi hindari melakukan itu.
Sumber: stackoverflow
sumber
onPause
,onStop
, maupunonResume
acara disebut. Jadi apa yang Anda lakukan jika tidak ada peristiwa ini yang dipecat ?!Jika menargetkan API level 14 atau lebih tinggi, seseorang dapat menggunakan android.app.Application.ActivityLifecycleCallbacks
sumber
UPD : diperbarui ke status
Lifecycle.State.RESUMED
. Terima kasih kepada @htafoya untuk itu.Di 2019 dengan bantuan pustaka dukungan baru
28+
atau AndroidX, Anda cukup menggunakan:Anda dapat membaca lebih lanjut di dokumentasi untuk memahami apa yang terjadi di balik terpal.
sumber
activity.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)
atau MEMULAI.INITIALIZED
tidak menjamin bahwa itu di latar depan.Activity :: hasWindowFocus () mengembalikan Anda boolean yang Anda butuhkan.
Berikut adalah contoh kelas untuk memeriksa visibilitas aktivitas Anda dari mana pun Anda berada.
Ingatlah bahwa jika Anda menampilkan dialog , hasilnya akan salah karena dialog akan memiliki fokus utama. Selain itu, ini sangat berguna dan lebih dapat diandalkan daripada solusi yang disarankan.
sumber
Itulah tepatnya perbedaan antara
onPause
danonStop
kejadian aktivitas seperti yang dijelaskan dalam dokumentasi kelas Aktivitas .Jika saya memahami Anda secara benar, yang ingin Anda lakukan adalah memanggil
finish()
dari aktivitas AndaonStop
untuk menghentikannya. Lihat gambar terlampir dari Aplikasi Demo Siklus Hidup Aktivitas . Ini adalah tampilannya ketika Aktivitas B diluncurkan dari Aktivitas A. Urutan kejadian adalah dari bawah ke atas sehingga Anda dapat melihat bahwa Aktivitas AonStop
dipanggil setelah Aktivitas BonResume
sudah dipanggil.Jika dialog ditampilkan, aktivitas Anda diredupkan di latar belakang dan hanya
onPause
dipanggil.sumber
Dua solusi yang mungkin:
1) Panggilan Balik Siklus Hidup Aktivitas
Gunakan Aplikasi yang mengimplementasikan ActivityLifecycleCallbacks dan menggunakannya untuk melacak kejadian daur hidup Aktivitas di aplikasi Anda. Perhatikan bahwa ActivityLifecycleCallbacks adalah untuk Android api> = 14. Untuk api Android sebelumnya, Anda harus mengimplementasikannya sendiri di dalam semua aktivitas Anda ;-)
Gunakan Aplikasi ketika Anda perlu membagikan / menyimpan status di seluruh aktivitas.
2) Periksa informasi proses yang sedang berjalan
Anda dapat memeriksa status proses yang berjalan dengan kelas ini RunningAppProcessInfo
Ambil daftar proses yang sedang berjalan dengan ActivityManager.getRunningAppProcesses () dan filter daftar hasil untuk memeriksa RunningAppProcessInfo yang diinginkan dan periksa "pentingnya"
sumber
Saya telah membuat proyek di github app-foreground-background-listen
yang menggunakan logika yang sangat sederhana dan berfungsi dengan baik dengan semua level API Android.
sumber
Gunakan jeda waktu antara jeda dan lanjutkan dari latar belakang untuk menentukan apakah itu terjaga dari latar belakang
Dalam Aplikasi Kustom
Di Kelas BaseActivity
sumber
Saya rasa saya punya solusi yang lebih baik. Karena Anda bisa membangun hanya dalam MyApplication.activityResumed (); untuk setiap Kegiatan dengan satu perluasan.
Pertama, Anda harus membuat (seperti CyberneticTwerkGuruOrc)
Selanjutnya, Anda harus menambahkan kelas Aplikasi ke AndroidManifest.xml
Kemudian, buat kelas ActivityBase
Terakhir, saat Anda membuat Activity baru, Anda cukup memperluasnya dengan ActivityBase alih-alih Activity.
Bagi saya Ini metode yang lebih baik karena Anda harus ingat tentang perluasan oleh ActivityBase. Selain itu, Anda dapat memperluas fungsi basis Anda di masa mendatang. Dalam kasus saya, saya menambahkan penerima untuk layanan saya dan peringatan tentang jaringan dalam satu kelas.
Jika Anda ingin memeriksa visibilitas Aplikasi Anda, Anda cukup menelepon
sumber
Ini bisa mencapai ini dengan cara yang efisien dengan menggunakan Application.ActivityLifecycleCallbacks
Sebagai contoh, mari kita ambil nama kelas Activity karena ProfileActivity memungkinkan menemukan apakah itu di latar depan atau latar belakang
pertama kita perlu membuat kelas aplikasi kita dengan memperluas Kelas Aplikasi
yang mengimplementasikan
Mari menjadi kelas Aplikasi saya sebagai berikut
Kelas aplikasi
di kelas di atas ada metode override onActivityResumed dari ActivityLifecycleCallbacks
di mana semua instance aktivitas yang saat ini ditampilkan di layar dapat ditemukan, cukup periksa apakah Aktivitas Anda ada di Layar atau tidak dengan metode di atas.
Daftarkan kelas Aplikasi Anda di manifest.xml
Untuk memeriksa cuaca, Aktivitas di Latar Depan atau latar belakang sesuai solusi di atas, panggil metode berikut di tempat-tempat yang perlu Anda periksa
sumber
Jika Anda ingin mengetahui apakah ada aktivitas aplikasi Anda yang terlihat di layar, Anda dapat melakukan sesuatu seperti ini:
Buat saja satu tunggal kelas ini dan setel dalam contoh Aplikasi Anda seperti di bawah ini:
Kemudian Anda bisa menggunakan metode isAnyActivityVisible () dari instance MyAppActivityCallbacks Anda di mana saja!
sumber
apakah Anda mencoba untuk tidak memanggil finish, dan meletakkan "android: noHistory =" true "dalam manifes? ini akan mencegah aktivitas masuk ke tumpukan.
sumber
Saya harus mengatakan alur kerja Anda tidak dengan cara Android standar. Di Android, Anda tidak perlu melakukan
finish()
aktivitas jika ingin membuka aktivitas lain dari Intent. Untuk kenyamanan pengguna, Android memungkinkan pengguna untuk menggunakan tombol 'kembali' untuk kembali dari aktivitas yang Anda buka ke aplikasi Anda.Jadi biarkan sistem menghentikan aktivitas Anda dan menyimpan apa pun yang diperlukan saat aktivitas Anda dipanggil kembali.
sumber
Simpan bendera jika Anda dijeda atau dilanjutkan. Jika Anda melanjutkan, itu berarti Anda berada di latar depan
sumber
Salah satu solusi yang mungkin mungkin adalah menyetel tanda saat menampilkan dialog sistem dan kemudian di metode onStop dari siklus hidup aktivitas, periksa tanda tersebut, jika benar, selesaikan aktivitas.
Misalnya, jika dialog sistem dipicu oleh beberapa klik tombol, maka pendengar onclick mungkin akan menyukainya
dan di onstop aktivitas:
sumber
Mengapa tidak menggunakan siaran untuk ini? aktivitas kedua (yang perlu di up) bisa mengirim siaran lokal seperti ini:
kemudian tulis penerima sederhana dalam aktivitas splash:
dan daftarkan penerima baru Anda dengan LocalBroadcastManager untuk mendengarkan siaran dari aktivitas kedua Anda:
CATATAN bahwa Anda dapat menggunakan konstanta atau sumber daya string untuk string "pengenal siaran".
sumber
LocalBroadcastManager
siniJika Anda menggunakan
finish()
hanya untuk menghindari aplikasi baru untuk dimulai dalam tumpukan (tugas) aplikasi Anda, Anda dapat menggunakanIntent.FLAG_ACTIVITY_NEW_TASK
bendera, saat memulai aplikasi baru dan tidak memanggilfinish()
sama sekali. Menurut dokumentasi , ini adalah tanda yang akan digunakan untuk mengimplementasikan perilaku gaya "peluncur".sumber
Gunakan metode ini di dalam file
Activity
.isDestroyed()
isFinishing()
Kesalahan umum dengan
AsyncTask
adalah menangkap referensi yang kuat ke tuan rumahActivity
(atauFragment
):Ini menjadi masalah karena
AsyncTask
dapat dengan mudah hidup lebih lama dari induknyaActivity
, misalnya jika terjadi perubahan konfigurasi saat tugas sedang berjalan.Cara yang tepat untuk melakukannya adalah dengan membuat tugas Anda menjadi
static
kelas, yang tidak menangkap induknya, dan memegang referensi yang lemah ke hostActivity
:sumber
Berikut adalah solusi menggunakan
Application
kelas.Anda cukup menggunakannya seperti berikut,
Jika Anda memiliki referensi ke Aktivitas yang diperlukan atau menggunakan nama kanonik Aktivitas, Anda bisa mencari tahu apakah itu ada di latar depan atau tidak. Solusi ini mungkin tidak selalu mudah. Oleh karena itu, komentar Anda sangat kami terima.
sumber
Saya tidak tahu mengapa tidak ada yang berbicara tentang sharedPreferences, untuk Aktivitas A, menyetel SharedPreference seperti itu (misalnya di onPause ()):
Saya pikir ini adalah cara yang dapat diandalkan untuk melacak visibilitas aktivitas.
sumber
Akan
Activity.onWindowFocusChanged(boolean hasFocus)
berguna di sini? Itu, ditambah bendera tingkat kelas, sesuatu sepertiisFocused
ituonWindowFocusChanged
set, akan menjadi cara mudah untuk mengatakan pada setiap titik dalam aktivitas Anda jika terfokus atau tidak. Dari membaca dokumen, sepertinya ini akan disetel dengan benar ke "false" dalam situasi apa pun di mana aktivitas tidak secara langsung berada di "latar depan" fisik, seperti jika dialog sedang ditampilkan atau baki notifikasi ditarik ke bawah.Contoh:
sumber
Jika Anda menggunakan EventBus , itu sebagai metode yang disebut
hasSubscriberForEvent
yang dapat digunakan untuk memeriksa apakah sebuahActivity
fokus.sumber
Saya dulu suka,
jika aktivitas tidak di latar depan
akan mengembalikan nol. : = P
sumber