Bir uygulamanın etkinlik yığınındaki son etkinlik olup olmadığı nasıl kontrol edilir?


Yanıtlar:


116

GÜNCELLEME (Temmuz 2015):

Yana getRunningTasks () API 21 dan takip etmek daha iyidir, kullanımdan kaldırılan olsun raukodraug cevap veya Ed Burnette biri (ben ikincisini tercih ediyorum).


ActivityManager'ı kullanarak mevcut görevleri ve yığınlarını kontrol etme imkanı vardır .

Bu nedenle, bir etkinliğin son etkinlik olup olmadığını belirlemek için:

  • manifest'te android.permission.GET_TASKS izinlerini isteyin.
  • Aşağıdaki kodu kullanın:

    ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE );
    
    List<ActivityManager.RunningTaskInfo> taskList = mngr.getRunningTasks(10);
    
    if(taskList.get(0).numActivities == 1 &&
       taskList.get(0).topActivity.getClassName().equals(this.getClass().getName())) {
        Log.i(TAG, "This is last activity in the stack");
    }

Yukarıdaki kodun yalnızca tek bir göreviniz varsa geçerli olacağını lütfen unutmayın. Uygulamanız için çok sayıda görevin bulunma olasılığı varsa - Diğer taskList öğelerini kontrol etmeniz gerekir . Görevler ve Back Stack hakkında daha fazla bilgi edinin



25
H9kDroid doğru bir öneride bulundu. Seçilen cevap bir kesmedir. isTaskRoot()Yöntemi kullanarak bunu doğru şekilde yapmalısınız .
Süfyan

@Sufian özellikle nerede hackliyor? Kod mantıklıdır ve amaçlandıkları şekilde açık Android API'lerini kullanır (örneğin, getRunningTasks çalışan görevleri almak için kullanılmalıdır ve biri yalnızca bu görevleri analiz etmek amacıyla çağırmak isteyebilir). Get (0) 'ın kullanımı iyi belgelenmiştir ve mantıklıdır' Şu anda çalışmakta olan görevlerin bir listesini döndür, en yenileri sırayla önce ve daha eskileri olmak üzere '.
sandrstar

2
getRunningTasks () API seviyesi 21'de kullanımdan kaldırıldı.
gilchris

Parçalar için de aynı şeyi yapabilir miyim? Cevabınız evet ise nasıl? Lütfen yardım edin
Sagar Devanga

1
@ Bay Drew @ raukodraug'dan en yüksek oyu alan cevabı gördü
David Wasser

167

@ H9kDroid'in yorumunu, benzer soruları olan insanlar için en iyi cevap olarak burada yayınlayacağım .

Etkinliğin bir görevin kökü olup olmadığını öğrenmek için isTaskRoot () kullanabilirsiniz .

Umarım bu yardımcı olur


1
isTaskRoot'un nasıl kullanılacağı konusunda net olması için lütfen tek satırlık kod sağlayabilir misiniz? Teşekkürler.
Kaveesh Kanwal

18
@TheHunterif (isTaskRoot()) { // do something }
howettl

3
Tek sorun, <= 4.4'te bunun> = 5.x'ten farklı bir davranış sergilediğini görmemdir. Her zaman yanlış dönüyor gibi görünüyor.
chubbsondubs

Gelecekteki okuyucuların işini kolaylaştırmak için yorumlarda verilen örnek kodu yanıta eklemeyi düşünmeniz gerektiğini düşünüyorum.
Isac

mükemmel cevap. benim durumumda, kullanıcı bir bildirimi tıkladıktan sonra, uygulamayı daha önce kapatmışlarsa etkinlik kök olabilir
dave o grady

19

Umarım bu yeni başlayanlara yardımcı olur, Benim için iyi çalışan yukarıdaki cevaplara dayanarak, ayrıca kod pasajını paylaşıyorum, böylece uygulanması kolay olacak.

Çözüm: i kullanılan isTaskRoot()geri dönme doğruysa eğer mevcut etkinlik yalnızca yığınında faaliyettir ve eğer ben de davayı ele dışındaki i yerine yeni açılması yığınında son aktiviteye yığın seferde bazı etkinlikler var özel bir.

Aktivitenizde

   @Override
    public void onBackPressed() {

        if(isTaskRoot()){
            startActivity(new Intent(currentActivityName.this,ActivityNameYouWantToOpen.class));
            // using finish() is optional, use it if you do not want to keep currentActivity in stack
            finish();
        }else{
            super.onBackPressed();
        }

    }


5

Bunu başarmanın bir yolu olsa da (diğer cevaplara bakın) bunu yapmamanızı öneririm. Normal Android uygulamalarının Ana ekranın görüntülenip görüntülenmeyeceğini bilmesine gerek yoktur.

Verileri kaydetmeye çalışıyorsanız, veri kaydetme kodunu onPause () yönteminize yerleştirin. Kullanıcıya uygulamanın mevcut olmasıyla ilgili fikrini değiştirmesi için bir yol vermeye çalışıyorsanız, Geri tuşu ve onBackPressed () yöntemi için yukarı / aşağı tuşunu durdurabilir ve onlara "Emin misiniz?" Komut istemi.


1
Kullanıcı aktiviteden ayrılmadığı sürece çalışan bir hizmete ihtiyacım olursa nasıl olur? OnStop gibi işlevlerden hiçbirini yakalayamıyorum çünkü bunlar ekran kapandıktan sonra çağrılabilir.
Michael

2
Bir arka plan hizmeti bir Etkinlik başlatırsa, belki de yığındaki tek Etkinlik olup olmadığını bilmek istersiniz.
Matt W

4

Bunu takip etmenin bir yolu, yeni bir aktiviteye başladığınızda bir işaretçi eklemek ve işaretin var olup olmadığını kontrol etmektir.

Yeni bir aktiviteye başladığınız her seferde, işaretçiyi ekleyin:

newIntent=new Intent(this, NextOne.class);
newIntent.putExtra(this.getPackageName()+"myself", 0);
startActivity(newIntent);

Ve daha sonra şu şekilde kontrol edebilirsiniz:

boolean islast=!getIntent().hasExtra(this.getPackageName()+"myself")

1
Aktivite öldürülürse ve aktivite yığını yeniden oluşturulursa - her aktivite talebe göre - işe yaramaz.
AlikElzin-kilaka

3

Sandrstar'ın çözümünün kullanılmasıyla ilgili sorun ActivityManagerşudur: görevleri bu şekilde almak için bir izne ihtiyacınız var. Daha iyi bir yol buldum:

getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)

ActivityDiğer Etkinlikler alamadım gerekirken, Yığın altta daima varsayılan olarak bu kategoriyi almalısınız.
Ancak bu bazı cihazlarda başarısız olsa bile, aşağıdakileri başlatırken ayarlayabilirsiniz Activity:

Intent intent = new Intent(startingActivity, SomeActivityClass.class);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
activity.startActivity(intent);

Aktivite push bildiriminden açılırsa ne olur? KATEGORİ
BAŞLATICISI

Cevabımın ikinci kısmının hala geçerli olduğundan oldukça eminim. Kategoriyi amaçta bir ipucu olarak ayarlayabilirsiniz. Bu durumda, bildirim bağlamınızın amacı olabilir. Bunun dışında bunun için bayrakları da kullanabilirsiniz. niyet içeren bir bildirim oluşturmak için bu bağlantıya bakın: stackoverflow.com/questions/13716723/…
A. Binzxxxxxx

Yine de, en eski etkinliğiniz MainActivity ise ve şimdi devam ettirildiyse ve ardından push bildirimi alırsanız ve pendingIntent'i CATEGORY_LAUNCHER ile açılacak şekilde ayarlarsanız, bu kategoriyle 2 etkinliğiniz olur. Muhtemelen farklı görevlerde
nbtk

Bildirimlerle nasıl çalıştığından tam olarak emin değilim. Senin burada yaptığın gibi onları hiç kullanmadım. Bunu yapmanın kolay bir yolu olduğundan eminim ama 2014'ün 1. çeyreğinden beri android koduna dokunmadım. Belki bu durum için ikinci bir kategori kullanmak istersiniz? Veya biraz bayrak? Ama sanırım bu şekilde çalışması gerekiyor. Peki, ana etkinliği başlatmaya ve doğru etkinliği açmak için bir tür meta bilgi eklemeye ne dersiniz?
A. Binzxxxxxx

2

Tüm etkinliklerim için AppCompatActivity'yi genişleten ve statik bir sayacı olan bir temel sınıf oluşturdum :

public abstract class BasicActivity extends AppCompatActivity {
    private static int activityCounter = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ++activityCounter;
        ...
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        --activityCounter;
        if(activityCounter==0) {
            // Last instance code...
        }
    }

    public boolean isLastInstance() { return (activityCounter==1); }
}

Bu şimdiye kadar yeterince iyi çalıştı; ve API sürümünden bağımsız olarak. Tabii ki, tüm faaliyetlerin bu temel sınıfı genişletmesini gerektirir - benim durumumda yaptıkları.

Düzenleme: Uygulama tamamen çıkmadan önce sayaç sıfıra düştüğünde, yön değiştirildiğinde ve yalnızca bir etkinliğin açık olduğu bir örnek fark ettim. Oryantasyon değiştiğinde, aktivite kapatılır ve bir başkası oluşturulur, bu nedenle onDestroyedson aktivite onCreateiçin çağrılır ve ardından aynı aktivite değiştirilen oryantasyon ile oluşturulduğunda çağrılır. Bu davranış hesaba katılmalıdır; OrientationEventListener muhtemelen kullanılabilir.


0

Android bir Etkinlik yığını uygular, bunun hakkında burada okumanızı öneririm . Bu is arama faaliyeti almak olsa yapmak istediğim gibi tüm görünür: getCallingActivity(). Geçerli etkinlik uygulamanızdaki ilk etkinlikse ve uygulama ana ekrandan başlatıldıysa geri dönmelidir (sanırım) null.


9
Etkinlik startActivityForResult () aracılığıyla başlatılmamışsa getCallingActivity () null döndüreceğinden bu işe yaramayacaktır.
H9kDroid

0

Burada kaçırılan tek şey, "Ana Sayfa tuşu" tıklamasıdır, etkinleştirildiğinde bunu faaliyetinizden tespit edemezsiniz, bu nedenle "Geri tuşuna" basıp gerekli etkinliğe geçerek programlı olarak etkinlik yığınını kontrol etmek daha iyi olur sadece gerekli adımları yapıyor.

Ayrıca, etkinliğinizin "Son Etkinlik" listesinden başlatılmasının, bu durumda yeniden kullanıldığı için açılış etkinliği için bazı ekstra verileri önceden ayarlayarak algılanabileceğinden emin olamazsınız.

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.