Android akan mematikan proses jika berada di latar belakang dan OS memutuskan perlu sumber daya (RAM, CPU, dll.). Saya harus dapat mensimulasikan perilaku ini selama pengujian sehingga saya dapat memastikan bahwa aplikasi saya berperilaku dengan benar. Saya ingin dapat melakukan ini dengan cara otomatis sehingga saya dapat menguji apakah aplikasi berperilaku dengan benar setiap kali ini terjadi, yang berarti bahwa saya harus menguji ini dalam setiap kegiatan, dll.
Saya tahu cara membunuh proses saya. Bukan itu masalahnya. Masalahnya adalah bahwa ketika saya membunuh proses saya (menggunakan DDMS, adb shell kill
, Process.killProcess()
, dll) Android tidak restart dengan cara yang sama bahwa hal itu akan jika OS Android telah membunuh itu sendiri.
Jika OS Android membunuh proses (karena kebutuhan sumber daya), ketika pengguna kembali ke aplikasi Android akan membuat ulang proses dan kemudian membuat kembali aktivitas teratas pada tumpukan aktivitas (panggilan onCreate()
).
Di sisi lain, jika saya mematikan proses, Android mengasumsikan bahwa aktivitas di atas tumpukan aktivitas berperilaku buruk , sehingga secara otomatis membuat ulang proses dan kemudian menghapus aktivitas teratas dari tumpukan aktivitas dan menciptakan kembali aktivitas yang ada di bawahnya. aktivitas teratas (memanggil onCreate () `). Ini bukan perilaku yang saya inginkan. Saya ingin perilaku yang sama seperti ketika Android membunuh prosesnya.
Hanya untuk menjelaskan secara gambar, jika tumpukan aktivitas saya terlihat seperti ini:
ActivityA -> ActivityB -> ActivityC -> ActivityD
Jika Android membunuh proses dan pengguna kembali ke aplikasi, Android menciptakan kembali proses dan membuat ActivityD.
Jika saya menghentikan proses, Android menciptakan ulang proses dan membuat ActivityC.
Jawaban:
Cara terbaik untuk menguji ini untuk saya adalah dengan melakukan ini:
Terminate Application
di jendela Logcat di Android Studio (ini akan mematikan proses aplikasi, pastikan Anda memilih perangkat Anda dan memproses dropdown Logcat di bagian atas)Pada beberapa perangkat Anda juga dapat kembali ke aplikasi (ActivityD) dengan Aplikasi -> ikon peluncur Anda tetapi di perangkat lain itu akan memulai ActivityA sebagai gantinya.
Inilah yang dikatakan Android docs tentang hal itu:
sumber
<activity>
tag di manifes.Ini sepertinya bekerja untuk saya:
Ini berbeda dengan yang
adb shell kill
disebutkan oleh OP.Perhatikan bahwa bantuan untuk
am kill
perintah tersebut mengatakan:Jadi, itu tidak akan mematikan proses jika berada di latar depan. Ini tampaknya berfungsi seperti yang diinginkan OP dalam hal itu jika saya menavigasi keluar dari aplikasi saya, kemudian menjalankannya
adb shell am kill <package_name>
akan mematikan aplikasi (Saya telah mengkonfirmasi ini menggunakanps
pada perangkat). Kemudian jika saya kembali ke aplikasi saya kembali ke aktivitas yang saya lakukan sebelumnya - yaitu dalam contoh OP proses akan dibuat kembali dan menciptakan ActivityD (daripada ActivityC seperti kebanyakan metode pembunuhan lainnya tampaknya memicu).Maaf saya terlambat beberapa tahun untuk OP, tapi mudah-mudahan orang lain akan menemukan ini berguna.
sumber
adb shell am force-stop
. Yang terakhir juga akan menghapus segala pendingIntent yang terkait dengan aplikasi Anda (seperti Notifikasi) sementara yang pertama tidak.am kill
.ps
menunjukkan aplikasi sayaMetode lain, mungkin salah satu yang dapat skrip karena tidak memerlukan DDMS:
Pengaturan satu kali: buka Opsi Pengembang, pilih pengaturan batas proses Latar Belakang, ubah nilai dari 'Batas Standar' ke 'Tidak ada proses latar belakang'.
Saat Anda perlu memulai kembali proses, tekan tombol beranda. Proses akan dimatikan (Anda dapat memverifikasi di logcat / Android Monitor di studio - proses akan ditandai [MATI]). Kemudian beralih kembali ke aplikasi menggunakan pengalih tugas.
sumber
Pertanyaan ini sudah lama tetapi, ada jawaban untuk pertanyaan ini yang tidak memerlukan adb, Android Studio dll. Satu-satunya persyaratan adalah API 23 atau lebih baru.
Untuk mensimulasikan restart aplikasi oleh OS, buka pengaturan aplikasi saat aplikasi Anda berjalan, nonaktifkan (lalu Anda dapat mengaktifkan) izin dan kembalikan aplikasi dari aplikasi terbaru. Ketika izin dinonaktifkan, OS membunuh aplikasi tetapi menyimpan status instance yang disimpan. Saat pengguna mengembalikan aplikasi, aplikasi dan aktivitas terakhir (dengan status tersimpan) dibuat kembali.
Metode 'Tidak ada proses latar belakang' terkadang menyebabkan perilaku yang sama, tetapi tidak selalu. Misalnya, jika aplikasi menjalankan layanan latar belakang, "Tidak ada proses latar belakang" tidak melakukan apa-apa. Tetapi aplikasi dapat dibunuh oleh sistem termasuk layanannya. Metode izin berfungsi bahkan jika aplikasi memiliki layanan.
Contoh:
Aplikasi kami memiliki dua kegiatan. ActivityA adalah aktivitas utama yang dimulai dari launcher. ActivityB dimulai dari ActivityA. Saya hanya akan menunjukkan metode onCreate, onStart, onStop, onDestroy. Android memanggil onSaveInstanceState selalu sebelum memanggil onStop, karena aktivitas yang dalam keadaan berhenti dapat dimatikan oleh sistem. [ https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle]
Metode izin:
Saya ingin membandingkan metode lain yang disebutkan pada jawaban lainnya.
Jangan simpan aktivitas: Ini tidak mematikan aplikasi.
Metode penghentian paksa: Tidak menyimpan status instance yang disimpan
sumber
Service
tewas banyak kali. Bahkan jika sistemnya tidak kehabisan memori. Sebagian besar produsen perangkat telah menulis "optimasi" dan "perbaikan" mereka sendiri untuk OS Android untuk menghemat daya baterai. Banyak perangkat memiliki "pembunuh" yang lebih agresif daripada Android standar.Saya sangat terlambat ke pesta dan beberapa sebelum saya memberikan jawaban yang benar sama tetapi untuk menyederhanakan bagi siapa pun yang datang setelah saya cukup tekan tombol home dan jalankan perintah ini:
adb shell ps | grep <package name> | awk '{print $2}' | xargs adb shell run-as <package name again> kill
Aplikasi tidak akan kehilangan status dan dari pengalaman saya sendiri ini bekerja dengan cara yang sama seperti OS membunuh aplikasi di latar belakang. Ini hanya berfungsi untuk debug aplikasi yang dibangun
sumber
'grep' is not recognized as an internal or external command, operable program or batch file.
run-as <package name> kill 7379
, tapi itu menempatkan saya di aktivitas sebelumnya, bukan aktivitas yang saya lakukan ketika saya menekan tombol home.Ini adalah bagaimana Anda melakukannya di Android Studio.
sumber
Android Monitor - Monitors
. Pasti sesuatu yang mereka singkirkan. Saya menggunakan v 3.2.1Tempatkan aplikasi di latar belakang dengan tombol HOME
Pilih proses Anda dalam mode "Logcat" di Android Studio, lalu klik Hentikan Aplikasi di sudut kiri bawah
Sekarang luncurkan aplikasi Anda dari launcher di perangkat Android
EDIT: Menurut internet, berikut ini juga berfungsi:
Sunting dari masa depan: Sesuatu yang perlu diperhatikan, ada perubahan di Android Studio 4.0, jika Anda gunakan
Run
dari AS, makaTerminate
akan mengeluarkanForce Stop
.Namun, jika Anda meluncurkan dari peluncur sesudahnya, dan MAKA Anda mencoba mensimulasikannya dengan cara ini, maka Anda akan mendapatkan hasil yang Anda inginkan (perilaku memori rendah).
sumber
the behaviour is not the same as what happens when Android kills the process
ya ituAnda dapat melakukan langkah selanjutnya untuk mereproduksi perilaku yang dicari:
sumber
Dalam opsi Pengembang di bawah Pengaturan, pilih 'Jangan simpan aktivitas', yang akan menghancurkan aktivitas segera setelah Anda menavigasi darinya.
Catatan: Sesuai dengan komentar bermanfaat di bawah ini, hanya gunakan ini jika Anda tidak peduli dengan nilai statis yang dihapus.
sumber
Tekan tombol Rumah dan letakkan aplikasi di latar belakang terlebih dahulu. Kemudian hentikan atau matikan proses dari DDMS atau ADB.
sumber
Anda juga dapat terhubung ke perangkat / emulator Anda dari terminal dengan
adb shell
, lalu dapatkan PID dari proses Andaps | grep <your_package_name
dan jalankankill -9 <pid>
. Kemudian buka aplikasi yang diperkecil dari pemilih aplikasi terbaru dan itu akan memulai kembali aktivitas terakhirsumber
Akar masalah Anda tampaknya adalah bahwa Anda
Activity
berada di latar depan saat Anda mematikan proses.Anda dapat mengamati ini dengan menekan berhenti di DDMS ketika
Activity
terlihat (terjadi persis seperti yang Anda gambarkan) dan membandingkannya dengan menekan berhenti setelah rumah dan kemudian kembali ke aplikasi.Pastikan untuk
moveTaskToBack(true)
entah bagaimana dalam tes Anda.sumber
Saya tidak yakin ini adalah jawaban yang Anda cari, itu lebih seperti pemikiran logis.
Saya tidak berpikir bahwa Anda benar-benar dapat membuat tes sepenuhnya otomatis, satu-satunya cara untuk mensimulasikannya, itu akan membuatnya kembali, AKA memiliki banyak kegiatan sehingga Android akan membunuh aplikasi Anda.
Jadi ide atau saran saya adalah membuat aplikasi kecil lainnya, yang terus memunculkan aktivitas baru, hingga Android kehabisan memori dan mulai mematikan proses itu di latar belakang.
Sesuatu di antaranya:
Mulai aktivitas i -> Periksa proses yang berjalan jika aplikasi ada dalam daftar, tambahkan i dan mulai ulang loop tanpa menutup aktivitas saat ini, jika tidak -> kurangi i dan tutup aktivitas saat ini, kembali ke sebelumnya dan periksa kembali ...
sumber
Saat proses aplikasi mati, Android menelusuri catatan aktivitas (entri mewakili aktivitas di tumpukan riwayat), dan memutuskan mana yang akan disimpan dalam riwayat dan mana yang harus dihapus dari itu.
Salah satu poin utama di sini adalah
ActivityRecord
bidang yang disebuthaveState
, yang oleh para insinyur Kerangka Android digambarkan sebagai "sudahkah kita mendapatkan status aktivitas terakhir?".Secara default, Android menganggap bahwa aktivitas memiliki status. Aktivitas menjadi tanpa kewarganegaraan ketika aplikasi melaporkan ke layanan pengelola tugas aktivitas bahwa aktivitas telah dilanjutkan dan ini berlaku sampai aplikasi memberitahukan kerangka kerja bahwa aktivitas telah memasuki status Berhenti. Dengan kata sederhana,
haveState
nilai adalahfalse
antara aktivitasonResume()
yang dipanggil danonStop()
atauonSaveInstanceState()
dipanggil, tergantung pada versi target aplikasi.Dalam hal ini ActivityD tidak memiliki
android:stateNotNeeded="true"
atribut dalam manifes aplikasi dan saat ini sedang berjalan di latar depan, jadi Android menghapusnya dari sejarah karena sistem belum mendapatkan status terakhirnya.Seperti yang telah disebutkan beberapa kali, Anda dapat dengan mudah memindahkan aplikasi ke latar belakang, sehingga aktivitas teratas dalam aktivitas back stack akan menyimpan statusnya, dan setelah itu Anda dapat mematikan proses aplikasi melalui Android Debug Bridge, Android Studio atau menggunakan Latar Belakang Proses Batasi properti di Opsi Pengembang. Setelah itu aktivitas terbaru Anda akan berhasil dibuat ulang.
Meskipun demikian, ada juga cara sederhana untuk menguji proses aplikasi skenario kematian. Mengetahui semua yang dijelaskan di atas dan fakta, bahwa jika Anda memulai ActivityE baru dari ActivityD yang sedang berjalan, maka
onStop()
callback ActivityD dipanggil hanya setelahonResume()
metode ActivityE , Anda dapat melakukan trik berikut.Maka mulailah saja
TerminatorActivity
ketika Anda ingin mematikan aplikasi.Pada akhirnya ada alat ringan yang menyederhanakan pengujian kematian proses aplikasi Anda, yang disebut Venom .
sumber