Pushwoosh che perde la mia attività

Sto usando Pushwoosh all'interno della mia applicazione per ricevere notifiche push. Sto utilizzando l'ultima versione della libreria 3.1.14 di Pushwoosh.

Ho una struttura dello schermo come questo.

  • Android MediaMuxer non è riuscito a smettere
  • Impostazione della dimensione di un DialogFragment
  • Android ListView setOnScrollListener
  • Maneggiare tre pulsanti fare clic sull'evento nella notifica personalizzata in android
  • Problema EditText TextChangeListener
  • Come visualizzare un dialogo da un servizio
  • Login Activity -> Main Activity with multiple tabs. 

    Quindi implemento la mia logica relativa a pushwoosh all'interno di MainActivity. E voglio annullare la logging da spingere su Logout e tornare all'attività di accesso.

    Il mio codice è riportto di seguito. Ho filtrato tutte le sezioni non correlate a Pushwoosh. Per essere sinceri, questo codice è esattamente simile al codice riportto nella documentazione di Pushwoosh. L'unica differenza è nel metodo onLogout () where cerco di annullare la logging da pushwoosh e tornare a LoginActivity.

    TabbarActivity.java

     @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //Pushwoosh Registration registerReceivers(); PushManager pushManager = PushManager.getInstance(this); pushManager.setNotificationFactory(new PushNotificationFactory()); try { pushManager.onStartup(this); } catch(Exception e) {} //Register for push! pushManager.registerForPushNotifications(); checkMessage(getIntent()); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); checkMessage(intent); } @Override protected void onResume() { super.onResume(); registerReceivers(); } @Override protected void onPause() { super.onPause(); unregisterReceivers(); } BroadcastReceiver mBroadcastReceiver = new BaseRegistrationReceiver() { @Override public void onRegisterActionReceive(Context context, Intent intent) { checkMessage(intent); } }; private BroadcastReceiver mReceiver = new BasePushMessageReceiver() { @Override protected void onMessageReceive(Intent intent) { //JSON_DATA_KEY contains JSON payload of push notification. } }; public void registerReceivers() { IntentFilter intentFilter = new IntentFilter( getPackageName() + ".action.PUSH_MESSAGE_RECEIVE"); registerReceiver(mReceiver, intentFilter, getPackageName() +".permission.C2D_MESSAGE", null); registerReceiver(mBroadcastReceiver, new IntentFilter( getPackageName() + "." + PushManager.REGISTER_BROAD_CAST_ACTION)); } public void unregisterReceivers() { try { unregisterReceiver(mReceiver); } catch (Exception e) { e.printStackTrace(); } try { unregisterReceiver(mBroadcastReceiver); } catch (Exception e) { e.printStackTrace(); } } private void checkMessage(Intent intent) { if (null != intent) { if (intent.hasExtra(PushManager.REGISTER_EVENT)) { uploadPushTokenToServer(PushManager.getPushToken(this)); } resetIntentValues(); } } private void resetIntentValues() { Intent mainAppIntent = getIntent(); if (mainAppIntent.hasExtra(PushManager.PUSH_RECEIVE_EVENT)) { mainAppIntent.removeExtra(PushManager.PUSH_RECEIVE_EVENT); } else if (mainAppIntent.hasExtra(PushManager.REGISTER_EVENT)) { mainAppIntent.removeExtra(PushManager.REGISTER_EVENT); } else if (mainAppIntent.hasExtra(PushManager.UNREGISTER_EVENT)) { mainAppIntent.removeExtra(PushManager.UNREGISTER_EVENT); } else if (mainAppIntent.hasExtra(PushManager.REGISTER_ERROR_EVENT)) { mainAppIntent.removeExtra(PushManager.REGISTER_ERROR_EVENT); } else if (mainAppIntent.hasExtra(PushManager.UNREGISTER_ERROR_EVENT)) { mainAppIntent.removeExtra(PushManager.UNREGISTER_ERROR_EVENT); } setIntent(mainAppIntent); } //Finally on logout private void onLogout() { //other cleanup //pushwoosh PushManager.getInstance(this).unregisterForPushNotifications(); //goback to login activity } 

    Sto ottenendo spinte dal server senza alcun problema. L'unico problema che affronto è dopo che mi allontano e tornerò a LoginActivity, TabbarActivity rimane in memory, che a sua volta tiene su molti altri frammenti e viste. Ho provato a eseguire il debug utilizzando MAT e questo è ciò che mostra.

     Class Name | Ref. Objects | Shallow Heap | Ref. Shallow Heap | Retained Heap -------------------------------------------------------------------------------------------------------------------------------------------------- com.pushwoosh.internal.request.RequestManager$1 @ 0x12f89ce0 Thread-1737 Thread| 1 | 88 | 360 | 536 '- val$context in.myproject.activities.TabbarActivity @ 0x12d8ac40 | 1 | 360 | 360 | 18,520 -------------------------------------------------------------------------------------------------------------------------------------------------- 

    Ho anche verificato la stessa cosa con lo strumento LeakCanary, che indica anche che Pushwoosh sta prendendo parte alla mia attività.

    Quindi la mia domanda è, come posso pulire il pushwoosh per evitare che la mia attività venga persa?

  • Autenticazione cookie Jsoup da cookiesyncmanager per raschiare dal sito https
  • Errore "App non installato" in Android
  • Le integrazioni di Flurry con Android App forniscono un errore "Imansible trovare la class com.flurry.sdk.i", indicata dal metodo com.flurry.sdk.hu.a "
  • Può una visualizzazione personalizzata sapere che onPause è stato chiamato?
  • Android aspetta un altro risultato di attività - non funzionava
  • Nascondere la barra degli strumenti sullo scorrimento con recyclerview all'interno del frammento
  • 3 Solutions collect form web for “Pushwoosh che perde la mia attività”

    I documenti che hai fatto riferimento, non guardarli brevemente, stanno dando un esempio e questi esempi non sono sempre il modo migliore per attuare l'API in un'applicazione completamente funzionale con altre attività. Capisco utilizzando getInstance, si sta tentando di utilizzare un singolo, ma sospetto che questo non sia gestito bene.

    Vorrei prendere il controllo dell'istanza di PushManager che viene utilizzato per la durata della tua app.

    Il problema può essere l'istanza multipla di PushManager creata sia dall'ambito e creando più istanze di pushManager all'interno della class, e possibilmente all'interno della vita del programma. Ciò causerà perdite.

    Farò pushManager una variabile di class piuttosto che usare PushManager.getInstance due volte e considerare la creazione di un'istanza statica del PushManager da utilizzare per la durata dell'app, come utilizzare un'istanza di singola database in un'applicazione.

    A livello di class:

     PushManager pushManager; 

    e inizializzare in oncreate

     pushManager = PushManager.getInstance(this); //Finally on logout private void onLogout() { //other cleanup //pushwoosh // Here the first instance is left dangling. // PushManager.getInstance(this).unregisterForPushNotifications(); pushManager..unregisterForPushNotifications(); //goback to login activity } 

    In questo modo hai ripulito le risorse per l'istanza di pushmanager.

    Per utilizzare un PushManager statico ampio:

     static PushManager pushManager; 

    inizializzato come:

     pushManager = new PushManager(this.getApplicationContext()); 

    Quando è un Singleton non un Singleton?

    Il commento di CommonsWare è puntuale. Guardando il codice sorgente (decompilato) del Pushwoosh SDK, PushManager.onStartUp() inoltra il context fornito direttamente al suo RequestManager , che a sua volta consegna a una Thread che continua a continuare a funzionare infinitamente. Significa che appenderà l'istanza di attività a lungo dopo che è diventato invalido.

    Notate come questo è esattamente quello che MAT sta cercando di dirti (e LeakCanary troppo probabilmente).

    In altre parole, all'interno di un forte riferimento si terrà a qualsiasi cosa si passa in onStartUp() , per la durata della tua applicazione. In tal caso, assicurati che il context fornito disponga di un ciclo di vita appropriato. In altre parole: l' unica opzione corretta è il context dell'applicazione.

    È ansible che si desideri archiviare un report di bug con Pushwoosh e informarli che il problema è:

     public void onStartup(Context context) throws Exception { Context applicationContext = context.getApplicationContext(); this.pushRegistrar.checkDevice(applicationContext); sendAppOpen(context); // <--- ISSUE ... } 

    Posso solo indovinare qualcuno ha avuto un brutto giorno in ufficio e dimenticato di cambiare la linea problematica in sendAppOpen(applicationContext) .

    Nessuna promise che tutte le perdite saranno storia dopo questo cambiamento (non ho scavato troppo nella fonte), ma dovrebbe alless risolvere il problema immediato a portta di mano.

    Inoltre, e questo non può essere sottolineato abbastanza, in generale, se non si conosce (o controlla) il tempo di vita di un componente, utilizzare il context dell'applicazione. Se un'attività è veramente necessaria, la firma del metodo dovrà / dovrebbe indicare così. Se sta solo chiedendo un context, gioca al sicuro. (E sì, ovviamente ci sono molte eccezioni a questa regola, ma in genere è più facile tracciare i problemi che causano questo problema piuttosto che quelli di perdite di memory).

    Beh, ho ricevuto una risposta da Pushwoosh dicendo che hanno risolto il problema. Ho scaricato il loro ultimo SDK e voila, la perdita era andata. E sembra che l'utente @MH sia in grado di identificare il codice colpevole.

    Questo è dal codice sorgente decompilato di nuovo SDK,

     public void onStartup(Context context) throws Exception { Context applicationContext = context.getApplicationContext(); this.pushRegistrar.checkDevice(applicationContext); sendAppOpen(applicationContext); // <--- NO ISSUE ... } 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.