Android'in işlemimi öldürme simülasyonu


174

Android, arka planda ise ve işletim sistemi kaynaklara (RAM, CPU, vb.) İhtiyaç duyduğuna karar verirse bir işlemi öldürecektir. Uygulamamın doğru bir şekilde çalıştığından emin olmak için test sırasında bu davranışı simüle edebilmem gerekiyor. Uygulamanın bu gerçekleştiğinde doğru davranıp davranmadığını test edebilmem için otomatik bir şekilde yapabilmek istiyorum, yani her etkinlikte test etmek zorunda kalacağım.

Süreci nasıl öldüreceğimi biliyorum. Sorun bu değil. Sorun benim sürecini öldürdüğünde (DDMS kullanarak olmasıdır adb shell kill, Process.killProcess()Android Bir o Android işletim bunu kendisini öldürdüğünü olsaydı aynı şekilde yeniden başlamazsa, vs.).

Android işletim sistemi işlemi (kaynak gereksinimleri nedeniyle) öldürürse, kullanıcı uygulamaya geri döndüğünde Android işlemi yeniden oluşturur ve daha sonra etkinlik yığınındaki (arama onCreate()) en üstteki etkinliği yeniden oluşturur .

Öte yandan, ben süreci öldürmek, Android etkinlik yığının tepesine etkinliği kötü davrandım olduğunu varsayar otomatik sürecini yeniden yüzden, ardından etkinlik yığınından üst aktivitesini kaldırır ve altından oldu aktiviteyi yeniden oluşturur üst etkinlik (onCreate () `çağrılıyor). İstediğim davranış bu değil. Android'in süreci öldürmesi ile aynı davranışı istiyorum.

Sadece resimsel olarak açıklamak için, eğer aktivite yığınım şöyle görünüyorsa:

    ActivityA -> ActivityB -> ActivityC -> ActivityD

Android işlemi öldürür ve kullanıcı uygulamaya geri dönerse, Android işlemi yeniden oluşturur ve ActivityD oluşturur.

İşlemi öldürürsem, Android işlemi yeniden oluşturur ve ActivityC oluşturur.


4
Yalnızca arka planda kendinizinkini öldürmek için gereken süreçleri oluşturamaz mısınız?
Alex W


2
@Pang Bence bu noktayı kaçırıyorsun. Android'in süreci öldürdüğünü nasıl tespit edeceğimi biliyorum. Bu koşulları idare eden bir kodum var. Ne yapmak istiyorum düzgün (ve otomatik bir şekilde) bu kodu test etmektir . Bunu yapmak için, Android'i sürecimi normalde kaynak baskısı altında olduğu gibi öldürmesi için kışkırtmanın bir yoluna ihtiyacım var. Bağlantılı soru ilginç olsa da, burada hiçbir değer katmıyor.
David Wasser


@IgorGanapolsky Bağlantılar için teşekkürler, ancak aslında bu bağlantıların hiçbirinin soruna çözümleri yoktur.
David Wasser

Yanıtlar:


127

Bunu benim için test etmenin en iyi yolu bunu yapmaktı:

  • Uygulamanızda ActivityD'yi açın
  • Ana Ekran düğmesine basın
  • Terminate ApplicationAndroid Studio'daki Logcat penceresine basın (bu, uygulama işlemini öldürür, cihazınızı seçtiğinizden ve üstteki Logcat açılır listelerinde işlem yaptığınızdan emin olun)
  • Ana Ekrana uzun basma veya açılmış uygulamalarla (cihaza bağlı olarak) uygulamaya geri dönün
  • Uygulama yeniden oluşturulan ActivityD'de başlayacak (ActivityA, ActivityB, ActivityC öldü ve geri döndüğünüzde yeniden oluşturulacak)

Bazı cihazlarda Uygulamalar -> Başlatıcı simgenizle uygulamaya (ActivityD) geri dönebilirsiniz, ancak diğer cihazlarda bunun yerine ActivityA başlatılır.

Android dokümanlarının bu konuda söylediği şey:

Normalde, kullanıcı bir görevi ana ekrandan yeniden seçtiğinde, sistem belirli durumlarda bir görevi temizler (kök etkinliğinin üstündeki yığından tüm etkinlikleri kaldırır). Genellikle, kullanıcı görevi 30 dakika gibi belirli bir süre ziyaret etmediğinde yapılır.


2
Cevabınız için teşekkürler, ancak benim için yararlı değil çünkü otomatik test için bunu yapmanın otomatik bir yoluna ihtiyacım var.
David Wasser

1
Bu benim için gerçekten çok yardımcı oldu.
John Roberts

6
Bu otomatik değil ama benim amacım için mükemmel çalıştı. 2. adımı atlamamak çok önemlidir . Bunun çalışması için DDMS'de işlemi durdurmadan önce uygulamayı arka plana göndermelisiniz. Doc tırnak bunun nereden geldiğini merak edenler için var burada . <activity>Manifest'teki etiketle ilgili olduğundan konuyla gerçekten ilgili olduklarından emin olmasam da.
Tony Chan

1
Tam olarak ihtiyacım olan şey. Teşekkür ederim. Bilmeyenler için DDMS Eclipse'de, Pencere -> Perspektifi Aç'a gidin ve orada bulmalısınız.
Richard

4
Alternatif olarak, "Geliştirme seçenekleri" ne gidebilir ve arka plan sınırını "arka plan işlemi yok" olarak ayarlayabilirsiniz.
Joao Gavazzi

56

Bu benim için işe yarıyor gibi görünüyor:

adb shell am kill <package_name>

Bu adb shell killOP tarafından belirtilenden farklıdır .

am killKomutun yardımının şunları söylediğine dikkat edin:

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

Yani, eğer ön planda ise süreci öldürmez. Bu, OP'nin istediğim gibi çalıştığı anlaşılıyor, eğer uygulamamdan uzaklaşırsam, uygulamayı çalıştırır adb shell am kill <package_name>(bunu pscihazda kullanarak onayladım ). Sonra uygulamaya dönersem, daha önce bulunduğum aktiviteye geri döndüm - yani OP'nin örneğinde süreç yeniden oluşturulur ve ActivityD oluşturur (diğer öldürme yöntemlerinin çoğu gibi tetikleyici gibi görünüyor).

Üzgünüm OP için birkaç yıl geç kaldım, ama umarım diğerleri bunu faydalı bulacaktır.


Teşekkürler! Aradığım şey buydu! Bu komutun bundan farklı davrandığını belirtmek istiyorum adb shell am force-stop. Sonuncusu, uygulamanızla ilgili (Bildirimler gibi) herhangi bir bekleyen
bonnyz

Belleği geri almak için bir işlemi öldürdüğünde hangi kodun çalıştığını görmek için işletim sistemi kaynak kodunu araştıran herkese işaret eder - bahse girerim aynı kodla aynıdır am kill.
androidguy

Android 7.1 Samsung J5 üzerinde çalışmaz. psbenim app gösterir
Valgaal

17

Başka bir yöntem, muhtemelen DDMS gerektirmediği için yazılabilir bir yöntemdir:

Tek seferlik kurulum: Geliştirici Seçenekleri'ne gidin, Arka plan işlemi sınır ayarı'nı seçin, 'Standart Sınır' dan 'Arka plan işlemi yok' olarak değeri değiştirin.

İşlemi yeniden başlatmanız gerektiğinde, ana sayfa düğmesine basın. İşlem öldürülecek (stüdyoda logcat / Android Monitor'de doğrulayabilirsiniz - işlem [DEAD] olarak işaretlenecektir). Ardından görev değiştiriciyi kullanarak uygulamaya geri dönün.


2
İlginç. Bunun Ön Plan Hizmetlerini etkilemediğini düşünüyorum, değil mi?
IgorGanapolsky

Bunu 2.3.3 kadar eski Android çalıştıran gerçek cihazlarda yapmam gerekiyor, bu yüzden bu herhangi bir yardım değil.
David Wasser

13

Bu soru eskidir, ancak bu soru için adb, Android Studio vb. Gerektirmeyen bir cevap vardır. Tek gereksinim API 23 veya daha yenisidir.

İşletim sistemi tarafından uygulamanın yeniden başlatılmasını simüle etmek için, uygulamanız çalışırken uygulama ayarlarına gidin, bir izni devre dışı bırakın (ardından etkinleştirebilirsiniz) ve uygulamayı son uygulamalardan döndürün. İzin devre dışı bırakıldığında, işletim sistemi uygulamayı öldürür ancak kaydedilen örnek durumlarını korur. Kullanıcı uygulamayı döndürdüğünde, uygulama ve son etkinlik (kaydedilmiş durumla birlikte) yeniden oluşturulur.

'Arka plan işlemi yok' yöntemi bazen aynı davranışa neden olur, ancak her zaman değil. Örneğin, uygulama bir arka plan hizmeti çalıştırıyorsa, "Arka plan işlemi yok" hiçbir şey yapmaz. Ancak uygulama hizmetleri de dahil olmak üzere sistem tarafından öldürülebilir. Uygulamada bir hizmet olsa bile izin yöntemi çalışır.

Misal:

Bizim app iki faaliyet vardır. ActivityA, başlatıcıdan başlatılan ana etkinliktir. ActivityB, ActivityA'dan başlatılır. Yalnızca onCreate, onStart, onStop, onDestroy yöntemlerini göstereceğim. Android, onStop'u çağırmadan önce her zaman onSaveInstanceState'i çağırır, çünkü durma durumunda olan bir etkinlik sistem tarafından öldürülebilir. [ https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle]

İzin yöntemi:

<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

Diğer cevaplarda bahsedilen diğer yöntemleri karşılaştırmak istiyorum.

Faaliyetleri tutmayın: Bu, uygulamayı öldürmez.

<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

Zorla durdurma yöntemi: Kayıtlı örnek durumlarını saklamaz

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

~ " uygulaması hizmeti dahil sistem tarafından öldürülebilir ". Ön Plan Hizmeti Değil ...
IgorGanapolsky

@DavidWasser Özellikleri okuyun! developer.android.com/guide/components/services.html#Foreground Ön plan hizmeti, kullanıcının etkin olarak farkında olduğu ve belleği yetersiz olduğunda sistemin öldürmesi için aday olmayan bir hizmettir.
IgorGanapolsky

3
@IgorGanapolsky Belgeler güzel, özellikle de tam ve doğru ise (ki maalesef değil), ama genellikle gerçek kişisel gözlemlere daha fazla güveniyorum. ServiceBolca öldürülen bir ön plan gördüm . Sistemin belleği az olsa bile. Çoğu cihaz üreticisi, pil gücünden tasarruf etmek için Android işletim sistemine kendi "optimizasyonlarını" ve "geliştirmelerini" yazdı. Birçok cihaz, standart Android'den çok daha agresif "katiller" e sahiptir.
David Wasser

@DavidWasser Adil gözlem. Bunca yıldan sonra bir çözüm buldunuz mu?
IgorGanapolsky

Hayır. Bu soruna bir çözüm bulamadım. Bu yüzden soru hala açık.
David Wasser

7

Partiye çok geç kaldım ve benden önce birkaç aynı cevabı verdi ama benden sonra gelenleri basitleştirmek için ev düğmesine basın ve bu komutu çalıştırın:

adb shell ps | grep <package name> | awk '{print $2}' | xargs adb shell run-as <package name again> kill

Uygulama durumu kaybetmeyecek ve kendi deneyimimden bu, işletim sisteminin uygulamayı arka planda öldürdüğü gibi çalışıyor. Bu yalnızca hata ayıklama yerleşik uygulamalar için çalışır


Anladım'grep' is not recognized as an internal or external command, operable program or batch file.
Dale

Ama bunu kabuktayken yaptım run-as <package name> kill 7379, ama ev düğmesine bastığım zamanki aktiviteyi değil, önceki aktiviteye soktum.
Dale

6

Android Studio'da böyle yaparsınız.

  1. Cihazınızın Hata Ayıklama Modunda bilgisayarınıza bağlı olmasını sağlayın.
  2. Cihazınızda uygulamayı açın ve "Ölüden dön" test etmek istediğiniz herhangi bir etkinliğe gidin.
  3. Cihazınızdaki Ana Ekran düğmesine basın.
  4. Android Studio'da Android Monitör -> Monitörler'e gidin ve Uygulamayı Sonlandır simgesine basın.
  5. Artık son uygulamalar aracılığıyla uygulamanıza geri dönebilir veya başlatıcı simgesine tıklayarak davranışlarım testlerimde aynı olmuştur.

2
Bu hiç bir yardım değil. Bunu bir test paketinde programlı olarak yapmam gerekiyor. Yinede teşekkürler.
David Wasser

Ayrıca, bu cevap Mark'ın cevabı ile hemen hemen aynı.
David Wasser

Bunu UIAutomator veya Espresso ile nasıl yapacağınız hakkında bir fikriniz var mı?
IgorGanapolsky

Bulamıyorum Android Monitor - Monitors. Kurtuldukları bir şey olmalı. Ben v 3.2.1
Dale

1
@Dale Android Device Monitor, Android Studio 3.1'de kullanımdan kaldırıldı ve Android Studio 3.2'den kaldırıldı.
Valgaal

5

HOME düğmesiyle uygulamayı arka plana yerleştirin

Android Studio'da "Logcat" modunda işleminizi seçin, ardından alt sol köşedeki Uygulamayı Sonlandır'ı tıklayın

sonlandır düğmesi

Şimdi uygulamanızı Android cihazdaki başlatıcıdan başlatın


EDIT: İnternete göre, aşağıdakiler de çalışır:

 adb shell am kill [my-package-name]

Gelecekten DÜZENLEME: nota bir şey kullanırsanız, Android Studio 4.0 bir değişiklik olmamıştır RunAS den sonra Terminatebir yayınlayacaktır Force Stop.

Ancak, daha sonra başlatıcıdan başlatırsanız ve daha sonra bu şekilde simüle etmeye çalışırsanız, istediğiniz sonuçları alırsınız (düşük bellek davranışı).


Bu yinelenen bir cevaptır
Onik

@Onik Diğer tüm ddms gibi bir sürü gereksiz tüyler var. Teknik olarak evet olsa da, stackoverflow.com/a/41975750/2413303 de aynı şeyi söylüyor. Belki resim eklemeliyim.
EpicPandaForce

Bu yardımcı olmuyor. Bir test kayışım var ve bu eylemleri test kayışından yapamıyorum. Ayrıca, davranış, Android işlemi öldürdüğü zamankiyle aynı değildir.
David Wasser

the behaviour is not the same as what happens when Android kills the processevet öyle
EpicPandaForce

Bu işlem, ev düğmesine basıldığında gerçekleşen etkinliği değil, önceki etkinliği gösterir.
Dale

2

İstenen davranışı yeniden oluşturmak için sonraki adımları gerçekleştirebilirsiniz:

  1. Uygulamanızı açın, en üst etkinliğe gidin
  2. Başka bir tam ekran uygulamasına gitmek için bildirim panelini kullanın (örneğin, sistem ayarlarına - sağ üst köşede)
  3. Başvuru sürecinizi öldürün
  4. Geri düğmesine basın

1
Cevabınız için teşekkürler, ancak benim için yararlı değil çünkü otomatik test için bunu yapmak için otomatik bir yola ihtiyacım var.
David Wasser

Yani, bu aslında Android temizleme belleği taklit ve uygulamanızı öldürmek taklit ettiğim tek yöntemdir (API seviyem 19 ve bu yüzden send-trim-memory komutunu kullanamıyorum). Adb shell am-stop com.my.app.package veya kill gibi diğer komutlar, yukarıdaki prosedürü izleyerek aynı işlemi yeniden oluşturmayacaktır!
Mark Garcia

2

Ayarlar altındaki Geliştirici seçeneklerinde, etkinliklerden ayrılır ayrılmaz etkinlikleri yok edecek olan 'Etkinlikleri tutma' seçeneğini belirtin.

Not: Aşağıdaki yararlı bir yoruma göre, bunu yalnızca statik değerlerin silinmesini önemsemiyorsanız kullanın.


Bu, bir yıl önce yayınlanan ve reddedilen çözümle etkili bir şekilde aynıdır. Tek fark, onu bir emülatöre ayarlamak için kullanılan uygulama, onu destekleyen daha yeni telefonlara benziyor.
Chris Stratton

1
Üzgünüz, Chris Stratton'un dediği gibi, bu diğer cevapla hemen hemen aynı öneri. Bu Android bitirme etkinlikleri ile ilgili değil. Bu, Android'in tüm süreci öldürmesiyle ilgili (özellikle Android 4.x çalıştıran HTC cihazlarda oldukça düzenli ve etkili).
David Wasser

6
Bu neredeyse iyi ama süreci öldürmeyecek, sadece etkinliği yok edecek. Bu ne demek? Etkinliğiniz saveInstanceState ile açılacak, ancak tüm statik değişkenler hala işlemde. İşlemden sonra tüm statik değişkenler de temizlenir.
Mark

1

Ana Ekran düğmesine basın ve uygulamayı önce arka plana koyun. Ardından işlemi DDMS veya ADB'den durdurun veya öldürün.


Cevabınız için teşekkürler, ancak benim için yararlı değil çünkü otomatik test için bunu yapmak için otomatik bir yola ihtiyacım var.
David Wasser

Etkinliğiniz şu anda ön plandaysa Android hiçbir zaman işleminizi öldürmeyecektir. Asla gerçekleşmeyecek bir durumu test etmeye çalışıyorsunuz. Etkinliğiniz arka planda ise, durumu zaten kaydedilmiştir ve manuel olarak öldürmek ve Android'i düşük bellek altında öldürmek arasında bir fark yoktur, yani işlem sadece öldürülür; düşük bellek öldürme konusunda özel bir şey yoktur. Bellek tekrar kullanılabilir olduğunda, yapışkan servisleriniz yeniden başlatılır (4.4 hariç) ve simgeye veya son göreve dokunduğunuzda, yığın ve etkinlik durumu geri yüklenir.
Monstieur

3
Örneğinizde, Etkinlik C'ye geri dönüyor çünkü Etkinlik D ekranda görünürken süreci öldürdünüz (bu asla düşük bellek altında bile gerçekleşmeyecek) ve Etkinlik C'nin durumu arka planda olduğu için kaydedildi. İşleminiz yalnızca ön planda değilse yani öldürülecektir, yani Aktivite D'nin durumu arka plana gittiğinde kaydedilmiş olacak ve böylece işleminiz öldürülse bile geri yüklenecektir. Her etkinlik üzerinde testlerinizi yapmak için, uygulamayı öldürmeden önce arka plana göndermeniz GEREKİR.
Monstieur

~ " İle uygulamayı arka plana koy " ile ne demek istediniz ?
IgorGanapolsky

1

Ayrıca cihazınıza / emülatörünüze terminalden bağlanabilir adb shell, ardından işleminizin PID'sini alabilir ps | grep <your_package_nameve yürütebilirsiniz kill -9 <pid>. Ardından, son uygulama seçiciden simge durumuna küçültülmüş uygulamanızı açın, son etkinliği yeniden başlatacak


Bu, Android'in düşük bellek koşullarında bir işlemi öldürmesi ile aynı şey midir? Bence OP özellikle bunu istedi ...
IgorGanapolsky

1
@IgorGanapolsky teorik olarak, eğer köklenmemişse gerçek bir cihazda yapamazsınız.
Fran Marzoa

0

Sorunun kökü Activity, süreci öldürdüğünüzde ön plana çıkmış gibi görünüyor .

Bunu Activitygörünür durumdayken (tam olarak açıkladığınız şekilde gerçekleşir) DDMS'de durdur'a basarak ve bunu evden sonra durmaya ve daha sonra uygulamaya geri dönerek karşılaştırarak gözlemleyebilirsiniz .

Sadece moveTaskToBack(true)testlerinizde bir şekilde emin olun .


0

Aradığınız yanıtın bu olduğundan emin değilim, daha çok mantık düşüncesine benziyor.

Gerçekten tam otomatik bir test yapabileceğinizi düşünmüyorum, simüle etmenin tek yolu, onu yeniden yaratmak olacak, AKA'nın Android'in uygulamanızı öldüreceği birçok aktivitesi var.

Benim fikrim veya önerim, Android hafızası tükenene ve arka planı işlemeye başlayana kadar yeni aktiviteler açmaya devam eden başka bir küçük uygulama yapmak.

Hattın arasında bir şey var:

Etkinliği başlat i -> Uygulama listede bulunuyorsa çalışan işlemi kontrol edin, i'yi artırın ve geçerli etkinliği kapatmadan döngüyü yeniden başlatın, aksi takdirde -> i'yi azaltın ve mevcut etkinliği kapatın, önceki haline dönün ve tekrar kontrol edin ...


0

Uygulama süreci sona erdiğinde, Android etkinlik kayıtlarından geçer (girişler geçmiş yığınındaki etkinlikleri temsil eder) ve geçmişte hangilerinin saklanacağına ve hangilerinin kaldırılacağına karar verir .

Buradaki anahtar noktalardan biri olduğunu ActivityRecordadlandırılan alan haveStateAndroid Çerçeve mühendisleri, tarif olarak "Biz aldık geçen etkinlik durumunu?".

Varsayılan olarak, Android etkinliğin bir durumu olduğunu düşünür . Uygulama , etkinliğin devam ettiği etkinlik görev yöneticisi hizmetine rapor verdiğinde etkinlik durumsuz hale gelir ve bu, uygulama etkinliğin Durduruldu durumuna girdiğini bildirene kadar geçerlidir . Basit bir ifadeyle, değer, uygulama hedef sürümüne bağlı olarak aktivite olarak çağrılır ve veya çağrılır .haveStatefalseonResume()onStop()onSaveInstanceState()

İşlemi öldürürsem, Android işlemi yeniden oluşturur ve ActivityC oluşturur.

Bu durumda, ActivityD android:stateNotNeeded="true"uygulama bildiriminde bir özniteliğe sahip değildir ve şu anda ön planda çalışmaktadır, bu nedenle sistem son durumuna gelmediğinden Android bunu geçmişten kaldırır.

Android'in işlemimi öldürme simülasyonu

Birkaç kez bahsedildiği gibi, uygulamayı arka plana taşıyabilirsiniz, böylece etkinlik geri yığınındaki en üst düzey etkinlik durumunu kaydeder ve bundan sonra Android Debug Bridge, Android Studio veya Arka Plan İşlemleri Geliştirici Seçeneklerindeki Limit özelliği. Bundan sonra son etkinliğiniz başarıyla yeniden oluşturulacaktır.

Buna rağmen, başvuru süreci ölüm senaryosunu test etmenin başka bir basit yolu daha var. Yukarıda açıklananların tümünü ve şu anda çalışan ActivityD'den yeni ActivityE başlatırsanız, ActivityD onStop()geri aramasının yalnızca ActivityE onResume()yönteminden sonra çağrılması gerçeğini bilerek , aşağıdaki numarayı yapabilirsiniz.

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) {}
    }
}

Sonra sadece TerminatorActivityuygulamayı öldürmek istediğinizde başlayın .

Sonunda, Venom adı verilen başvuru sürecinizin ölümünün test edilmesini kolaylaştıran hafif bir araç var .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.