Cara mensimulasikan Android membunuh proses saya

174

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.

David Wasser
sumber
4
Tidak bisakah Anda hanya membuat jumlah proses yang diperlukan untuk membunuh proses Anda di latar belakang?
Alex W
2
@ Pang Saya pikir Anda tidak mengerti intinya. Saya tahu cara mendeteksi bahwa Android telah membunuh prosesnya. Saya punya kode yang menangani kondisi ini. Yang ingin saya lakukan adalah menguji kode ini dengan benar (dan dengan cara otomatis) . Untuk melakukan itu, saya perlu beberapa cara untuk dapat memprovokasi Android untuk membunuh proses saya dengan cara yang persis sama seperti yang biasanya dilakukan di bawah tekanan sumber daya. Pertanyaan yang ditautkan, meskipun menarik, tidak menambah nilai apa pun di sini.
David Wasser
@IgorGanapolsky Terima kasih atas tautannya, tetapi sebenarnya tidak ada tautan yang memiliki solusi untuk masalah ini.
David Wasser

Jawaban:

127

Cara terbaik untuk menguji ini untuk saya adalah dengan melakukan ini:

  • Buka ActivityD di aplikasi Anda
  • Tekan tombol Rumah
  • Tekan Terminate Applicationdi jendela Logcat di Android Studio (ini akan mematikan proses aplikasi, pastikan Anda memilih perangkat Anda dan memproses dropdown Logcat di bagian atas)
  • Kembali ke aplikasi dengan Home tekan lama atau aplikasi yang dibuka (tergantung pada perangkat)
  • Aplikasi akan mulai di ActivityD diciptakan (ActivityA, ActivityB, ActivityC sudah mati dan akan dibuat kembali ketika Anda kembali ke mereka)

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:

Biasanya, sistem menghapus tugas (menghapus semua aktivitas dari tumpukan di atas aktivitas root) dalam situasi tertentu ketika pengguna memilih kembali tugas itu dari layar beranda. Biasanya, ini dilakukan jika pengguna belum mengunjungi tugas untuk waktu tertentu, seperti 30 menit.

Menandai
sumber
2
Terima kasih atas jawaban Anda tetapi tidak berguna bagi saya karena saya memerlukan cara otomatis untuk melakukan ini, untuk pengujian otomatis.
David Wasser
1
Ini sangat membantu saya.
John Roberts
6
Ini tidak otomatis tetapi berfungsi dengan baik untuk tujuan saya. Sangat penting untuk tidak melewatkan langkah 2 . Anda harus mengirim aplikasi ke latar belakang sebelum menghentikan proses dalam DDMS agar ini berfungsi. Bagi mereka yang bertanya-tanya dari mana kutipan dokumen berasal dari sini . Meskipun saya tidak yakin mereka sebenarnya terkait dengan topik karena ini tentang <activity>tag di manifes.
Tony Chan
1
Apa yang saya butuhkan. Terima kasih. Bagi yang tidak tahu, DDMS ada di Eclipse, buka Window -> Open Perspective, dan Anda harus menemukannya di sana.
Richard
4
Atau Anda bisa pergi ke "Opsi pengembangan" dan menetapkan batas latar belakang ke "tidak ada proses latar belakang" maka setiap kali Anda menekan rumah proses akan mati.
Joao Gavazzi
56

Ini sepertinya bekerja untuk saya:

adb shell am kill <package_name>

Ini berbeda dengan yang adb shell killdisebutkan oleh OP.

Perhatikan bahwa bantuan untuk am killperintah tersebut mengatakan:

am kill: Kill all processes associated with <PACKAGE>.  Only kills.
  processes that are safe to kill -- that is, will not impact the user
  experience.

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 menggunakan pspada 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.

HexAndBugs
sumber
Terima kasih! inilah yang saya cari! Saya ingin menentukan bahwa perintah ini berperilaku berbeda dari adb shell am force-stop. Yang terakhir juga akan menghapus segala pendingIntent yang terkait dengan aplikasi Anda (seperti Notifikasi) sementara yang pertama tidak.
bonnyz
Poin ke siapa pun yang menyelidiki kode sumber OS untuk melihat kode apa yang berjalan ketika itu membunuh proses untuk merebut kembali memori - taruhan saya adalah kode yang sama am kill.
androidguy
tidak bekerja di Android 7.1 Samsung J5. psmenunjukkan aplikasi saya
Valgaal
17

Metode 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.

Merk
sumber
2
Menarik. Saya pikir itu tidak mempengaruhi Layanan Foreground, kan?
IgorGanapolsky
Saya perlu melakukan ini pada perangkat yang sebenarnya menjalankan Android setua 2.3.3, jadi ini tidak membantu.
David Wasser
13

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:

<start app from launcher first time>
Application onCreate
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
<open ActivityB>
ActivityB onCreate WITHOUT savedInstance
ActivityB onStart
ActivityA onStop (the order is like this, it is stopped after new one is started)
<go settings>
ActivityB onStop
<disable a permission>
//Application is killed, but onDestroy methods are not called.
//Android does not call onDestroy methods if app will be killed.
<return app by recent apps>
Application onCreate (this is the important part. All static variables are reset.)
ActivityB onCreate WITH savedInstance (user does not notice activity is recreated)
//Note that ActivityA is not created yet, do not try to access it.
ActivityB onStart
<return ActivityA by back>
ActivityA onCreate WITH savedInstance (user does not notice activity is recreated)
ActivityA onStart
ActivityB onStop
ActivityB onDestroy
<press back again, return launcher>
ActivityA onStop
ActivityA onDestroy
<open app again>
//does not call Application onCreate, app was not killed
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart

Saya ingin membandingkan metode lain yang disebutkan pada jawaban lainnya.

Jangan simpan aktivitas: Ini tidak mematikan aplikasi.

<start app from launcher first time>
Application onCreate
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
<open ActivityB>
ActivityB onCreate WITHOUT savedInstance
ActivityB onStart
ActivityA onStop
ActivityA onDestroy (do not keep)
<return launcher by home button>
ActivityB onStop
ActivityB onDestroy (do not keep) 
<retun app from recent apps>
// NO Application onCreate
ActivityB onCreate WITH savedInstance (user does not notice activity recreated)
ActivityB onStart
<return ActivityA by back>
ActivityA onCreate WITH savedInstance (user does not notice activity recreated)
ActivityA onStart
ActivityB onStop
ActivityB onDestroy
<press back again, return launcher>
ActivityA onStop
ActivityA onDestroy
<open app again>
//does not call Application onCreate, app was not killed
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart

Metode penghentian paksa: Tidak menyimpan status instance yang disimpan

<start app from launcher first time>
Application onCreate
ActivityA onCreate WITHOUT savedInstance
ActivityA onStart
<open ActivityB>
ActivityB onCreate WITHOUT savedInstance
ActivityB onStart
ActivityA onStop
<go settings>
ActivityB onStop
<force stop, return app from recent apps>
Application onCreate
ActivityA onCreate WITHOUT savedInstance 
//This is important part, app is destroyed by user.
//Root activity of the task is started, not the top activity.
//Also there is no savedInstance.
fthdgn
sumber
~ " aplikasi dapat dibunuh oleh sistem termasuk layanannya ". Bukan Foreground Service ...
IgorGanapolsky
@ Davidvider Baca spec! developer.android.com/guide/components/services.html#Foreground Layanan foreground adalah layanan yang pengguna secara aktif sadari dan bukan kandidat sistem untuk mematikan saat kehabisan memori.
IgorGanapolsky
3
@IgorGanapolsky Dokumentasi bagus, terutama jika lengkap dan benar (yang sayangnya tidak), tapi saya biasanya lebih mengandalkan pengamatan pribadi yang sebenarnya. Saya telah melihat latar depan Servicetewas 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.
David Wasser
@DavidWasser Fair pengamatan. Jadi setelah bertahun-tahun, apakah Anda menemukan solusi?
IgorGanapolsky
@IgorGanapolsky Tidak. Saya tidak menemukan solusi untuk masalah ini. Itu sebabnya pertanyaannya masih terbuka.
David Wasser
7

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

Hirschen
sumber
Saya mendapatkan'grep' is not recognized as an internal or external command, operable program or batch file.
Dale
Tapi saya melakukannya saat berada di shell run-as <package name> kill 7379, tapi itu menempatkan saya di aktivitas sebelumnya, bukan aktivitas yang saya lakukan ketika saya menekan tombol home.
Dale
6

Ini adalah bagaimana Anda melakukannya di Android Studio.

  1. Apakah perangkat Anda dalam Mode Debug terhubung ke komputer Anda.
  2. Buka aplikasi di perangkat Anda dan pergi ke aktivitas apa pun yang Anda ingin menguji "Kembali ke sana dari kematian".
  3. Tekan tombol Rumah di perangkat Anda.
  4. Di Android Studio, masuk ke Android Monitor -> Monitor dan tekan ikon Terminate Application.
  5. Sekarang Anda dapat kembali ke aplikasi Anda melalui aplikasi terbaru atau dengan mengklik ikon peluncur itu, perilaku telah sama dalam pengujian saya.
dbar
sumber
2
Ini tidak membantu. Saya perlu melakukan ini secara programatis, dalam test suite. Tapi Terimakasih.
David Wasser
Juga, jawaban ini hampir sama dengan jawaban dari Mark.
David Wasser
Adakah yang tahu bagaimana melakukan ini melalui UIAutomator atau Espresso?
IgorGanapolsky
Saya tidak dapat menemukan Android Monitor - Monitors. Pasti sesuatu yang mereka singkirkan. Saya menggunakan v 3.2.1
Dale
1
@Dale Android Device Monitor sudah tidak digunakan lagi di Android Studio 3.1 dan dihapus dari Android Studio 3.2.
Valgaal
5

Tempatkan aplikasi di latar belakang dengan tombol HOME

Pilih proses Anda dalam mode "Logcat" di Android Studio, lalu klik Hentikan Aplikasi di sudut kiri bawah

mengakhiri tombol

Sekarang luncurkan aplikasi Anda dari launcher di perangkat Android


EDIT: Menurut internet, berikut ini juga berfungsi:

 adb shell am kill [my-package-name]

Sunting dari masa depan: Sesuatu yang perlu diperhatikan, ada perubahan di Android Studio 4.0, jika Anda gunakan Rundari AS, maka Terminateakan 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).

EpicPandaForce
sumber
Ini adalah jawaban rangkap
Onik
@ Onik Semua yang lain memiliki banyak bulu yang tidak perlu seperti ddms dan apa pun. Meskipun secara teknis ya, stackoverflow.com/a/41975750/2413303 mengatakan hal yang sama. Mungkin saya harus menambahkan gambar.
EpicPandaForce
Ini tidak membantu. Saya memiliki test harness dan saya tidak bisa melakukan tindakan ini dari test harness. Juga, perilaku tidak sama dengan apa yang terjadi ketika Android membunuh prosesnya.
David Wasser
the behaviour is not the same as what happens when Android kills the processya itu
EpicPandaForce
Proses ini menunjukkan kepada saya aktivitas sebelumnya, bukan aktivitas ketika tombol home ditekan.
Dale
2

Anda dapat melakukan langkah selanjutnya untuk mereproduksi perilaku yang dicari:

  1. Buka aplikasi Anda, navigasikan ke aktivitas teratas
  2. Gunakan panel notifikasi untuk menavigasi ke aplikasi layar penuh lainnya (misalnya, ke pengaturan sistem - di sudut kanan atas)
  3. Bunuh proses aplikasi Anda
  4. Tekan tombol kembali
Igor Kostomin
sumber
1
Terima kasih atas jawaban Anda tetapi tidak berguna bagi saya karena saya memerlukan cara otomatis untuk melakukan ini, untuk pengujian otomatis.
David Wasser
Jadi, ini adalah satu-satunya metode yang saya temukan yang benar-benar akan mensimulasikan Android membersihkan memori dan mematikan aplikasi Anda (level API saya adalah 19, dan jadi saya tidak dapat menggunakan perintah send-trim-memory). Perintah lain seperti adb shell am force-stop com.my.app.package atau kill, tidak akan mereproduksi proses yang sama persis dengan mengikuti prosedur di atas!
Mark Garcia
2

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.

MSpeed
sumber
Ini sama dengan solusi yang sudah diposting - dan ditolak - setahun yang lalu. Satu-satunya perbedaan tampaknya adalah aplikasi yang digunakan untuk mengaturnya di emulator, vs telepon yang lebih baru yang mendukungnya.
Chris Stratton
1
Maaf, seperti kata Chris Stratton, saran ini hampir sama dengan jawaban lainnya. Ini bukan tentang aktivitas penyelesaian Android. Ini tentang Android yang membunuh seluruh proses (yang dilakukannya, cukup teratur dan efektif, terutama pada perangkat HTC yang menjalankan Android 4.x).
David Wasser
6
Yang ini hampir bagus tetapi tidak akan mematikan prosesnya, itu hanya merusak aktivitas. Apa artinya? Aktivitas Anda akan dibuka dengan disimpanInstanceState tetapi semua variabel statis masih dalam proses. Setelah proses, bunuh semua variabel statis juga dihapus.
Markus
1

Tekan tombol Rumah dan letakkan aplikasi di latar belakang terlebih dahulu. Kemudian hentikan atau matikan proses dari DDMS atau ADB.

Monstieur
sumber
Terima kasih atas jawaban Anda tetapi tidak berguna bagi saya karena saya memerlukan cara otomatis untuk melakukan ini, untuk pengujian otomatis.
David Wasser
Android tidak akan pernah menghentikan proses Anda jika aktivitas Anda saat ini ada di latar depan. Anda mencoba menguji suatu kondisi yang tidak akan pernah terjadi. Jika aktivitas Anda ada di latar belakang, maka kondisinya telah disimpan dan tidak ada perbedaan antara Anda membunuhnya secara manual dan Android membunuhnya di bawah memori rendah yaitu prosesnya baru saja dimatikan; tidak ada yang istimewa dari memori rendah. Ketika memori tersedia lagi, layanan lengket Anda akan dihidupkan ulang (kecuali pada 4.4) dan ketika Anda mengetuk ikon atau tugas terakhir, tumpukan dan status aktivitas akan dipulihkan.
Monstieur
3
Dalam contoh Anda, ini akan kembali ke Aktivitas C karena Anda membunuh proses sementara Aktivitas D terlihat di layar (ini tidak akan pernah terjadi bahkan di bawah memori rendah) dan keadaan Aktivitas C disimpan karena berada di latar belakang. Proses Anda hanya akan terbunuh jika tidak ada di latar depan sama sekali, yaitu aktivitas Aktivitas D akan disimpan ketika pergi ke latar belakang dan dengan demikian akan dikembalikan bahkan jika proses Anda terbunuh. Untuk melakukan tes pada setiap aktivitas, Anda HARUS mengirim aplikasi ke latar belakang terlebih dahulu sebelum Anda membunuhnya.
Monstieur
Apa yang Anda maksud dengan ~ " dan menempatkan aplikasi di latar belakang "?
IgorGanapolsky
1

Anda juga dapat terhubung ke perangkat / emulator Anda dari terminal dengan adb shell, lalu dapatkan PID dari proses Anda ps | grep <your_package_namedan jalankan kill -9 <pid>. Kemudian buka aplikasi yang diperkecil dari pemilih aplikasi terbaru dan itu akan memulai kembali aktivitas terakhir

qbasso
sumber
Apakah itu sama dengan Android yang membunuh proses dalam kondisi memori rendah? Saya pikir OP secara khusus menginginkan itu ...
IgorGanapolsky
1
@IgorGanapolsky secara teoritis, meskipun Anda tidak bisa melakukan itu pada perangkat yang sebenarnya jika tidak di-root.
Fran Marzoa
0

Akar masalah Anda tampaknya adalah bahwa Anda Activityberada di latar depan saat Anda mematikan proses.

Anda dapat mengamati ini dengan menekan berhenti di DDMS ketika Activityterlihat (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.

MaciejGórski
sumber
0

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 ...

Emil Borconi
sumber
0

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 ActivityRecordbidang yang disebut haveState, 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, haveStatenilai adalah falseantara aktivitas onResume()yang dipanggil dan onStop()atau onSaveInstanceState()dipanggil, tergantung pada versi target aplikasi.

Jika saya menghentikan proses, Android menciptakan ulang proses dan membuat ActivityC.

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.

Cara mensimulasikan Android membunuh proses saya

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 setelah onResume()metode ActivityE , Anda dapat melakukan trik berikut.

class TerminatorActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val isPrePie = applicationInfo.targetSdkVersion < Build.VERSION_CODES.P
        val callbacks = TerminatorLifecycleCallbacks(isPrePie)
        (applicationContext as Application).registerActivityLifecycleCallbacks(callbacks)
    }

    private class TerminatorLifecycleCallbacks(
        // Before P onSaveInstanceState() was called before onStop(), starting with P it's
        // called after
        // Used to schedule the death as app reports server that activity has stopped
        // after the latest of these was invoked
        private val isPrePie: Boolean
    ) : ActivityLifecycleCallbacksDefault {

        private val handler = Handler(Looper.getMainLooper())

        override fun onActivityPostStopped(activity: Activity) {
            if (isPrePie) {
                terminate()
            }
        }

        override fun onActivityPostSaveInstanceState(activity: Activity, outState: Bundle) {
            if (!isPrePie) {
                terminate()
            }
        }

        fun terminate() {
            handler.postDelayed(
                {
                    Process.killProcess(Process.myPid()) // This is the end... 
                },
                LAST_MILLIS
            )
        }

        companion object {
            // Let's wait for a while, so app can report and server can handle the update
            const val LAST_MILLIS = 100L
        }

    }

    private interface ActivityLifecycleCallbacksDefault : Application.ActivityLifecycleCallbacks {
        override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
        override fun onActivityStarted(activity: Activity) {}
        override fun onActivityResumed(activity: Activity) {}
        override fun onActivityPaused(activity: Activity) {}
        override fun onActivityStopped(activity: Activity) {}
        override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
        override fun onActivityDestroyed(activity: Activity) {}
    }
}

Maka mulailah saja TerminatorActivity ketika Anda ingin mematikan aplikasi.

Pada akhirnya ada alat ringan yang menyederhanakan pengujian kematian proses aplikasi Anda, yang disebut Venom .

ivkil
sumber