Come ottenere l'attuale contesto di attività in primo piano in Android?


171

Ogni volta che la mia trasmissione viene eseguita, voglio mostrare un avviso all'attività in primo piano.


da dove vuoi ottenere il contesto dell'attività. Sarà questa la tua attività app o altra applicazione.
AAnkit,

questa è un'attività dell'app. Ho eseguito la codifica della finestra di dialogo di avviso sulla funzione onceceive () di broadcastreceiver.
Deepali,

un'attività app! questa è la tua app ?? e perché vuoi questo, per qualsiasi motivo, potrebbero esserci alternative per lo stesso
AAnkit

Voglio mostrare un avviso sulla mia attività in primo piano. È un altro modo per mostrare un avviso all'attività in primo piano senza contesto.
Deepali,

1
solo in ricezione ricevi COntext come parametro, puoi dire context.getApplicationContext ()
AAnkit

Risposte:


39

Sapendo che ActivityManager gestisce l' attività , in modo da poter ottenere informazioni da ActivityManager . Otteniamo l'attuale primo piano in esecuzione Activity

ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;

AGGIORNAMENTO 2018/10/03
getRunningTasks () è DEPRECATED. vedi le soluzioni di seguito.

Questo metodo è stato deprecato nel livello API 21. A partire da Build.VERSION_CODES.LOLLIPOP, questo metodo non è più disponibile per le applicazioni di terze parti: l'introduzione di recenti recenti incentrati sui documenti significa che può trasferire informazioni sulla persona al chiamante. Per compatibilità con le versioni precedenti, restituirà comunque un piccolo sottoinsieme dei suoi dati: almeno le attività del chiamante e, eventualmente, altre attività come la casa che non sono sensibili.


16
non credo Martin, dall'aiuto dell'SDK di getRunningTasks "Nota: questo metodo è destinato esclusivamente al debug e alla presentazione di interfacce utente per la gestione delle attività. Questo non dovrebbe mai essere usato per la logica di base in un'applicazione"
ruhalde

3
Apparentemente questo supporta solo un sottoinsieme limitato di attività in esecuzione in Android 5 / Lollipop.
Sam

7
La documentazione per ActivityManager.getRunningTasks () dice "Questo metodo è stato deprecato nel livello API 21".
marchi

210

( Nota: un'API ufficiale è stata aggiunta nell'API 14: vedere questa risposta https://stackoverflow.com/a/29786451/119733 )

NON USARE la risposta PRECEDENTE (waqas716).

Si verificherà un problema di perdita di memoria, a causa del riferimento statico all'attività. Per maggiori dettagli consultare il seguente link http://android-developers.blogspot.fr/2009/01/avoiding-memory-leaks.html

Per evitare ciò, è necessario gestire i riferimenti alle attività. Aggiungi il nome dell'applicazione nel file manifest:

<application
    android:name=".MyApp"
    ....
 </application>

La tua classe di applicazione:

  public class MyApp extends Application {
        public void onCreate() {
              super.onCreate();
        }

        private Activity mCurrentActivity = null;
        public Activity getCurrentActivity(){
              return mCurrentActivity;
        }
        public void setCurrentActivity(Activity mCurrentActivity){
              this.mCurrentActivity = mCurrentActivity;
        }
  }

Crea una nuova attività:

public class MyBaseActivity extends Activity {
    protected MyApp mMyApp;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mMyApp = (MyApp)this.getApplicationContext();
    }
    protected void onResume() {
        super.onResume();
        mMyApp.setCurrentActivity(this);
    }
    protected void onPause() {
        clearReferences();
        super.onPause();
    }
    protected void onDestroy() {        
        clearReferences();
        super.onDestroy();
    }

    private void clearReferences(){
        Activity currActivity = mMyApp.getCurrentActivity();
        if (this.equals(currActivity))
            mMyApp.setCurrentActivity(null);
    }
}

Quindi, ora invece di estendere la classe Activity per le tue attività, estendi MyBaseActivity. Ora puoi ottenere la tua attività corrente dall'applicazione o dal contesto Attività in questo modo:

Activity currentActivity = ((MyApp)context.getApplicationContext()).getCurrentActivity();

9
Potresti semplicemente usare WeakReference e ottenere lo stesso risultato con meno codice.
Nacho Coloma,

5
@Nacho Non consiglierei mai di utilizzare WeakReferencesin Android il GC li raccoglie più velocemente di quanto pensi.
rekire il

4
@MaximKorobov Sì, è possibile se si chiama finish () da onCreate (), se si utilizza l'attività solo per avviare un'altra attività e interromperla. In questo scenario salta onPause () e onStoo (). Vedi la nota di fondo di developer.android.com/training/basics/activity-lifecycle/…
Rodrigo Leitão

2
@rekire @NachoColoma L'uso di WeakReferencenon è consigliato per la memorizzazione nella cache, questa non è la memorizzazione nella cache, ovvero mCurrentActivityavrà un riferimento ad essa solo quando è viva, quindi WeakReferencenon verrà mai raccolta mentre Activityè in primo piano. Tuttavia, ciò che @NachoColoma suggerisce è sbagliato perché WeakReferencepotrebbe ancora fare riferimento a un'attività non ripresa (non viva / non in cima) se la variabile non viene cancellata!
TWiStErRob

14
A partire dal livello API 14 di Android dovrebbe essere possibile utilizzare Application .ActivityLifecycleCallbacks, che sarebbe più centrale e non dovresti aggiungere alcun codice di gestione in tutte le tue attività. Vedi anche developer.android.com/reference/android/app/…
Filou,

68

Espando in cima alla risposta di @ gezdy.

In ogni attività, invece di dover "registrarsi" con Application con la codifica manuale, possiamo utilizzare la seguente API dal livello 14, per aiutarci a raggiungere scopi simili con meno codifica manuale.

public void registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback)

http://developer.android.com/reference/android/app/Application.html#registerActivityLifecycleCallbacks%28android.app.Application.ActivityLifecycleCallbacks%29

In Application.ActivityLifecycleCallbacks, puoi ottenere qualeActivity è "attaccato" o "staccato" a questo Application.

Tuttavia, questa tecnica è disponibile solo dal livello API 14.


1
Che succede con tutte le altre risposte? Chiaramente questa è API progettata per questo scopo. Grazie, Cheok Yan Cheng
Michael Bushe,

2
@MichaelBushe - nel 2012, quando sono state scritte le altre risposte, a seconda del livello API 14 non era qualcosa su cui fare affidamento in ogni dispositivo, dato che l'API era stata rilasciata solo di recente (ottobre 2011).
ToolmakerSteve

4
Trovato una risposta che mostra come utilizzare questo approccio: stackoverflow.com/a/11082332/199364 Il vantaggio è che non è necessario fare nulla alle attività stesse ; il codice è tutto nella tua classe di callback personalizzata. Devi semplicemente creare una classe implements Application.ActivityLifecycleCallbackse aggiungere i metodi per implementarla. Quindi nel costruttore di quella classe (o onCreate o init o altro metodo che viene eseguito quando l'istanza sta diventando attiva / pronta), inserisci getApplication().registerActivityLifecycleCallbacks(this);come ultima riga.
ToolmakerSteve

Penso che la tua risposta sia la migliore
burulangtu,

2
Bella risposta. l'unico aspetto negativo è che è ancora necessario salvare l'attività in qualche posto se è necessario interrogare la classe per l'attività corrente. quindi è ancora necessario evitare la perdita di memoria e annullare il riferimento.
Raffaello C,

56

Aggiornamento 2 : è stata aggiunta un'API ufficiale per questo, utilizzare invece ActivityLifecycleCallbacks .

AGGIORNARE:

Come sottolineato da @gezdy, e te ne sono grato. imposta anche il riferimento su null per l'attività corrente, invece di aggiornarlo su ogni onResume impostalo su null su onDestroy di ogni attività per evitare problemi di perdita di memoria.

Qualche tempo fa avevo bisogno della stessa funzionalità ed ecco il metodo con cui l'ho raggiunto. In ogni tua attività ignora questi metodi del ciclo di vita.

@Override
protected void onResume() {
    super.onResume();
    appConstantsObj.setCurrentActivity(this);

}

@Override
protected void onPause() {
   clearReferences();
   super.onPause();
}

@Override
protected void onDestroy() {        
   clearReferences();
   super.onDestroy();
}

private void clearReferences(){
          Activity currActivity = appConstantsObj.getCurrentActivity();
          if (this.equals(currActivity))
                appConstantsObj.setCurrentActivity(null);
}

Ora nella tua classe di trasmissione puoi accedere all'attività corrente per mostrare un avviso su di essa.


3
Questa risposta dovrebbe davvero ottenere più voti positivi, soluzione semplice, ma potente quando hai lezioni che devono manipolare attività, ma non sono attività stesse.
ryvianstyron,

Si tratta solo di un riferimento statico dell'oggetto attività. Puoi crearlo dove vuoi :). Non importa
Waqas,

Questo è btw equivalente alla tua risposta precedente. Applicationviene creato una sola volta e mai immondizia raccolta esattamente come una variabile statica.
zapl

1
Ci saranno problemi con le attività gerarchiche. Quando torni da un'attività figlio a quella genitore: (1) è chiamato bambino in pausa; (2) onResume dei genitori; (3) onDestroy del bambino ==> l'attività corrente sarà nulla. Dovresti fare qualche controllo come @gezdy nel suo esempio nel metodo clearReferences.
Art

4
@ waqas716 Io suggerirei per semplificare la condizione in clearReferences()a (this.equals(currActivity)).
naXa,

51

@lockwobr Grazie per l'aggiornamento

Questo non funziona al 100% delle volte in api versione 16, se leggi il codice su github la funzione "currentActivityThread" è stata modificata in Kitkat, quindi voglio dire la versione 19ish, un po 'difficile da abbinare alla versione di api con le versioni in github .

Avere accesso alla corrente Activityè molto utile. Non sarebbe bello avere una staticagetActivity metodo che restituisca l'attività corrente senza domande inutili?

La Activityclasse è molto utile. Dà accesso al thread dell'interfaccia utente dell'applicazione, visualizzazioni, risorse e molti altri. Numerosi metodi richiedono un Context, ma come ottenere il puntatore? Ecco alcuni modi:

  • Tracciamento dello stato dell'applicazione mediante metodi di ciclo di vita sostituiti. Devi archiviare l'attività corrente in una variabile statica e devi accedere al codice di tutte le attività.
  • Tracciamento dello stato dell'applicazione tramite Strumentazione. Dichiara Strumentazione nel manifest, implementala e usa i suoi metodi per tracciare i cambiamenti di attività. Passando un puntatore Attività ai metodi e alle classi utilizzati nelle Attività. Iniettare il puntatore usando una delle librerie di iniezione di codice. Tutti questi approcci sono piuttosto scomodi ; fortunatamente, c'è un modo molto più semplice per ottenere l'attività corrente.
  • Sembra che il sistema abbia bisogno di accedere a tutte le attività senza i problemi sopra menzionati. Quindi, molto probabilmente c'è un modo per ottenere attività usando solo chiamate statiche. Ho trascorso molto tempo a cercare le fonti Android su grepcode.com e ho trovato quello che cercavo. C'è una classe chiamata ActivityThread. Questa classe ha accesso a tutte le attività e, per di più, ha un metodo statico per ottenere la correnteActivityThread . C'è solo un piccolo problema: l'elenco delle attività ha accesso al pacchetto.

Facile da risolvere usando la riflessione:

public static Activity getActivity() {
    Class activityThreadClass = Class.forName("android.app.ActivityThread");
    Object activityThread = activityThreadClass.getMethod("currentActivityThread").invoke(null);
    Field activitiesField = activityThreadClass.getDeclaredField("mActivities");
    activitiesField.setAccessible(true);

    Map<Object, Object> activities = (Map<Object, Object>) activitiesField.get(activityThread);
    if (activities == null)
        return null;

    for (Object activityRecord : activities.values()) {
        Class activityRecordClass = activityRecord.getClass();
        Field pausedField = activityRecordClass.getDeclaredField("paused");
        pausedField.setAccessible(true);
        if (!pausedField.getBoolean(activityRecord)) {
            Field activityField = activityRecordClass.getDeclaredField("activity");
            activityField.setAccessible(true);
            Activity activity = (Activity) activityField.get(activityRecord);
            return activity;
        }
    }

    return null;
}

Tale metodo può essere utilizzato ovunque nell'app ed è molto più conveniente di tutti gli approcci citati. Inoltre, sembra che non sia così pericoloso come sembra. Non introduce nuove potenziali perdite o puntatori nulli.

Lo snippet di codice sopra menzionato manca di gestione delle eccezioni e presume ingenuamente che la prima attività in esecuzione sia quella che stiamo cercando. Potresti voler aggiungere alcuni controlli aggiuntivi.

Post sul blog


2
in Kitkat e sopra mActivities non è HashMap, ma ArrayMap, quindi è necessario modificare questa riga: HashMap Activities = (HashMap) activitiesField.get (activityThread); assomigliare a questo: ArrayMap activities = (ArrayMap) activitiesField.get (activityThread);
Palejandro,

7
@Palejandro per supportare entrambi i livelli di API (sopra 18 e sotto) dovrebbe usare Mapinvece l'interfaccia HashMapo ArrayMap. Ho modificato la risposta @AZ_.
Yuriy Kolbasinskiy il

2
Questo non funziona al 100% delle volte in api versione 16 , se leggi il codice su github la funzione "currentActivityThread" è stata modificata in Kitkat, quindi voglio dire la versione 19ish , un po 'difficile da abbinare alla versione di api con le versioni in github .
Lockwobr,

@lockwobr grazie, soluzione aggiornata con il tuo commento
:)

2
L'accesso alle API interne tramite reflection non è supportato e potrebbe non funzionare su tutti i dispositivi o in futuro.
Pei,

9

Ho fatto il seguito a Kotlin

  1. Crea classe di applicazione
  2. Modifica la classe di applicazione come segue

    class FTApplication: MultiDexApplication() {
    override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(base)
        MultiDex.install(this)
    }
    
    init {
        instance = this
    }
    
    val mFTActivityLifecycleCallbacks = FTActivityLifecycleCallbacks()
    
    override fun onCreate() {
        super.onCreate()
    
        registerActivityLifecycleCallbacks(mFTActivityLifecycleCallbacks)
    }
    
    companion object {
        private var instance: FTApplication? = null
    
        fun currentActivity(): Activity? {
    
            return instance!!.mFTActivityLifecycleCallbacks.currentActivity
        }
    }
    
     }
  3. Creare la classe ActivityLifecycleCallbacks

    class FTActivityLifecycleCallbacks: Application.ActivityLifecycleCallbacks {
    
    var currentActivity: Activity? = null
    
    override fun onActivityPaused(activity: Activity?) {
        currentActivity = activity
    }
    
    override fun onActivityResumed(activity: Activity?) {
        currentActivity = activity
    }
    
    override fun onActivityStarted(activity: Activity?) {
        currentActivity = activity
    }
    
    override fun onActivityDestroyed(activity: Activity?) {
    }
    
    override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {
    }
    
    override fun onActivityStopped(activity: Activity?) {
    }
    
    override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
        currentActivity = activity
    }
    
    }
  4. ora puoi usarlo in qualsiasi classe chiamando il seguente: FTApplication.currentActivity()


5

getCurrentActivity () è anche in ReactContextBaseJavaModule.
(Poiché questa domanda è stata inizialmente posta, molte app Android hanno anche il componente ReactNative - app ibrida.)

la classe ReactContext in ReactNative ha l'intera serie di logiche per mantenere mCurrentActivity che viene restituita in getCurrentActivity ().

Nota: vorrei che getCurrentActivity () fosse implementato nella classe Applicazione Android.


in alcuni casi questo contesto di ReactContextBaseJavaModule è nullo, sai perché?
Moxor,

4

Non sono riuscito a trovare una soluzione di cui il nostro team sarebbe contento, quindi abbiamo creato la nostra. Usiamo ActivityLifecycleCallbacksper tenere traccia dell'attività corrente e quindi esporla attraverso un servizio. Maggiori dettagli qui: https://stackoverflow.com/a/38650587/10793


2

Per compatibilità con le versioni precedenti:

ComponentName cn;
ActivityManager am = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
    cn = am.getAppTasks().get(0).getTaskInfo().topActivity;
} else {
    //noinspection deprecation
    cn = am.getRunningTasks(1).get(0).topActivity;
}

4
A meno che non ci sia un modo per passare da ComponentName all'istanza corrente dell'Attività, questo non risponde alla domanda IMO.
nasch

@nasch si può mantenere e ottenere un WeakReferencehandle da una Applicationclasse, mentre ComponentNameè necessario per determinare se il desiderato Activityè in cima all'elenco delle attività in esecuzione. E se questo non risponde completamente alla domanda, neanche la risposta accettata.
Martin Zeitler,

Sono d'accordo, la risposta accettata non risponde completamente alla domanda.
nasch,

1
topActivityè disponibile solo da Android Q
Eugen Martynov,

1

Personalmente ho fatto come diceva "Cheok Yan Cheng", ma ho usato un "Elenco" per avere un "Backstack" di tutte le mie attività.

Se si desidera verificare qual è l'attività corrente, è sufficiente ottenere l'ultima classe di attività nell'elenco.

Creare un'applicazione che estenda "Applicazione" e procedere come segue:

public class MyApplication extends Application implements Application.ActivityLifecycleCallbacks,
EndSyncReceiver.IEndSyncCallback {

private List<Class> mActivitiesBackStack;
private EndSyncReceiver mReceiver;
    private Merlin mMerlin;
    private boolean isMerlinBound;
    private boolean isReceiverRegistered;

@Override
    public void onCreate() {
        super.onCreate();
        [....]
RealmHelper.initInstance();
        initMyMerlin();
        bindMerlin();
        initEndSyncReceiver();
        mActivitiesBackStack = new ArrayList<>();
    }

/* START Override ActivityLifecycleCallbacks Methods */
    @Override
    public void onActivityCreated(Activity activity, Bundle bundle) {
        mActivitiesBackStack.add(activity.getClass());
    }

    @Override
    public void onActivityStarted(Activity activity) {
        if(!isMerlinBound){
            bindMerlin();
        }
        if(!isReceiverRegistered){
            registerEndSyncReceiver();
        }
    }

    @Override
    public void onActivityResumed(Activity activity) {

    }

    @Override
    public void onActivityPaused(Activity activity) {

    }

    @Override
    public void onActivityStopped(Activity activity) {
        if(!AppUtils.isAppOnForeground(this)){
            if(isMerlinBound) {
                unbindMerlin();
            }
            if(isReceiverRegistered){
                unregisterReceiver(mReceiver);
            }
            if(RealmHelper.getInstance() != null){
                RealmHelper.getInstance().close();
                RealmHelper.getInstance().logRealmInstanceCount("AppInBackground");
                RealmHelper.setMyInstance(null);
            }
        }
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

    }

    @Override
    public void onActivityDestroyed(Activity activity) {
        if(mActivitiesBackStack.contains(activity.getClass())){
            mActivitiesBackStack.remove(activity.getClass());
        }
    }
    /* END Override ActivityLifecycleCallbacks Methods */

/* START Override IEndSyncCallback Methods */
    @Override
    public void onEndSync(Intent intent) {
        Constants.SyncType syncType = null;
        if(intent.hasExtra(Constants.INTENT_DATA_SYNC_TYPE)){
            syncType = (Constants.SyncType) intent.getSerializableExtra(Constants.INTENT_DATA_SYNC_TYPE);
        }
        if(syncType != null){
            checkSyncType(syncType);
        }
    }
    /* END IEndSyncCallback Methods */

private void checkSyncType(Constants.SyncType){
    [...]
    if( mActivitiesBackStack.contains(ActivityClass.class) ){
         doOperation()     }
}

}

Nel mio caso ho usato "Application.ActivityLifecycleCallbacks" per:

  • Bind / Unbind Merlin Instance (utilizzato per ottenere eventi quando l'app perde o ottiene la connessione, ad esempio quando si chiudono i dati mobili o quando li si apre). È utile dopo che l'azione di intento "OnConnectivityChanged" è stata disabilitata. Per ulteriori informazioni su MERLIN, consultare: LINK INFO MERLIN

  • Chiudi la mia ultima istanza di Realm quando l'applicazione è chiusa; Lo avvierò all'interno di una BaseActivity che è estesa da tutte le altre attività e che ha un'istanza RealmHelper privata. Per maggiori informazioni su REALM vedi: INFO LINK REALM Ad esempio ho un'istanza "RealmHelper" statica all'interno della mia classe "RealmHelper" che viene istanziata nella mia applicazione "onCreate". Ho un servizio di sincronizzazione in cui creo il nuovo "RealmHelper" perché Realm è "Thread-Linked" e un'istanza Realm non può funzionare all'interno di un thread diverso. Quindi, al fine di seguire la documentazione di Realm "È necessario chiudere tutte le istanze di Realm aperte per evitare perdite di risorse di sistema", per realizzare questa cosa ho usato "Application.ActivityLifecycleCallbacks" come puoi vedere.

  • Finalmente ho un ricevitore che viene attivato quando finisco di sincronizzare la mia applicazione, quindi quando termina la sincronizzazione chiamerà il metodo "IEndSyncCallback" "onEndSync" in cui cerco se ho una Classe di attività specifica all'interno del mio Elenco ActivityBackStack perché ho bisogno per aggiornare i dati nella vista se la sincronizzazione li ha aggiornati e potrei aver bisogno di fare altre operazioni dopo la sincronizzazione dell'app.

Questo è tutto, spero che sia utile. Ci vediamo :)


-1

La risposta di waqas716 è buona. Ho creato una soluzione alternativa per un caso specifico che richiede meno codice e manutenzione.

Ho trovato una soluzione specifica con un metodo statico per recuperare una vista dall'attività che sospetto fosse in primo piano. Puoi scorrere tutte le attività e verificare se lo desideri o ottenere il nome dell'attività dalla risposta di Martin

ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity; 

Quindi controllo se la vista non è nulla e ottengo il contesto tramite getContext ().

View v = SuspectedActivity.get_view();

if(v != null)
{
    // an example for using this context for something not 
    // permissible in global application context. 
    v.getContext().startActivity(new Intent("rubberduck.com.activities.SomeOtherActivity"));
}

Sto cercando un problema simile qui stackoverflow.com/questions/22788289/… come possiamo ottenere "SuspectedActivity"? Questa è API nativa?
Stella,

2
MA dai documenti per getRunningTasks: "Note: this method is only intended for debugging and presenting task management user interfaces. This should never be used for core logic in an application, ..." in developer.android.com/reference/android/app/…
ToolmakerSteve

3
La documentazione per ActivityManager.getRunningTasks () ora dice "Questo metodo è stato deprecato nel livello API 21".
marchi

-2

Non mi piace nessuna delle altre risposte. ActivityManager non è pensato per essere utilizzato per ottenere l'attività corrente. Super classing e in base a Distruggi è anche fragile e non è il miglior design.

Onestamente, il meglio che mi è venuto in mente finora è solo mantenere un enum nella mia applicazione, che viene impostato quando viene creata un'attività.

Un'altra raccomandazione potrebbe essere quella di evitare di usare più attività se possibile. Questo può essere fatto utilizzando frammenti o nelle mie preferenze visualizzazioni personalizzate.


1
un enum? In che modo aiuta a localizzare l'istanza corrente dell'attività in primo piano?
ToolmakerSteve

"Anche il super classing e in base a Distruggi è fragile" Com'è fragile?
ToolmakerSteve

-3

Una soluzione piuttosto semplice è quella di creare una classe manager singleton, in cui è possibile memorizzare un riferimento a una o più attività o qualsiasi altra cosa a cui si desidera accedere in tutta l'app.

Chiama UberManager.getInstance().setMainActivity( activity );onCreate dell'attività principale.

Chiama UberManager.getInstance().getMainActivity();ovunque nell'app per recuperarla. (Sto usando questo per essere in grado di usare Toast da un thread non UI.)

Assicurati di aggiungere una chiamata a UberManager.getInstance().cleanup();quando l'app viene distrutta.

import android.app.Activity;

public class UberManager
{
    private static UberManager instance = new UberManager();

    private Activity mainActivity = null;

    private UberManager()
    {

    }

    public static UberManager getInstance()
    {
        return instance;
    }

    public void setMainActivity( Activity mainActivity )
    {
        this.mainActivity = mainActivity;
    }

    public Activity getMainActivity()
    {
        return mainActivity;
    }

    public void cleanup()
    {
        mainActivity = null;
    }
}

Questo è invadente e richiede cambiamenti in tutte le attività. La risposta di AZ_ è molto migliore in quanto è totalmente localizzata e autonoma senza richiedere altre modifiche alla base di codice.
Marksp

-7

Sono in ritardo di 3 anni, ma risponderò comunque nel caso qualcuno lo trovi come ho fatto io.

Ho risolto questo semplicemente usando questo:

    if (getIntent().toString().contains("MainActivity")) {
        // Do stuff if the current activity is MainActivity
    }

Nota che "getIntent (). ToString ()" include un sacco di altro testo come il nome del pacchetto e qualsiasi filtro di intenti per la tua attività. Tecnicamente stiamo verificando l'intento attuale, non l'attività, ma il risultato è lo stesso. Basta usare ad esempio Log.d ("test", getIntent (). ToString ()); se vuoi vedere tutto il testo. Questa soluzione è un po 'confusa ma è molto più pulita nel tuo codice e la funzionalità è la stessa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.