in Android, JAVA, React-Native

Ricevere notifiche per onPause e onResume utilizzando React-Native su Android

Potrebbe capitarvi di utilizzare React-Native su piattaforma Android e di dover necessariamente gestire la vostra App in situazioni limite come, per esempio, l’uscita momentanea (onPause) e la riattivazione successiva alla chiusura (onResume).

Pur non presentando alcun metodo nativo (JS) che consenta di accedere al controllo dello stato dell’applicazione, React-Native offre tutti gli strumenti necessari per poter gestire tale casistica senza troppi problemi.

La soluzione è un modulo nativo personalizzato che si aggancia agli eventi del dispositivo e funge da mediatore tra il contesto Javascript e il processo dell’applicazione nativa consentendo la ricezione di notifiche rispetto al cambiamento di stato dell’app (messa in pausa o ripresa).

Per prima cosa dobbiamo realizzare una classe Java che lavori come modulo React-Native:

public class DeviceEventsModule 
  extends ReactContextBaseJavaModule implements LifecycleEventListener {

  @Override 
  public void onHostResume() {
    sendEvent("onResume");
  }

  @Override
  public void onHostPause() {
    sendEvent("onPause");
  }

  @Override
  public void onHostDestroy() {
    sendEvent("onDestroy");
  }

  private void sendEvent(String eventName) {
    // ... TO BE ... 
  }
}

L’oggetto realizzato estende la classe base ReactContextBaseJavaModule e implementa l’interfaccia LifecycleEventListener. L’utilizzo dell’interfaccia LifecycleEventListener richiede l’implementazione dei metodi onHostResume, onHostPause e onHostDestroy. Questi sono metodi invocati in corrispondenza degli eventi sopracitati. In ognuno di questi eventi ho aggiunto la chiamata ad un ulteriore metodo, sendEvent, di cui vi ripropongo di seguito l’implementazione:

private void sendEvent(String eventName) {
  ReactApplicationContext appContext = getReactApplicationContext();
  appContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
    .emit(eventName, null);
}

Questo non fa altro che attivare una comunicazione con l’oggetto react preposto all’inoltro delle notifiche al thread JS e, quando invocato, invia una notifica dell’evento specificato eventName.

Ora è necessario rendere disponibile questo modulo all’interno della nostra applicazione, sotto forma di modulo JS, questo lo si fa realizzando un ReactPackage:

public class AppPackage implements ReactPackage {
  @Override 
  public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
    return Arrays.<NativeModule>asList(new DeviceEventsModule(reactContext));
  }
}

Successivamente è opportuno registrare il pacchetto all’avvio dell’applicazione, all’interno dell’oggetto MainApplication, andando a modificare il metodo getPackages:

@Override
protected List<ReactPackage> getPackages() {
  return Arrays.asList(
    new MainReactPackage(),
    new AppPackage()
  );
}

Terminato lo sviluppo nativo, possiamo finalmente integrate, all’interno della nostra app, la gestione degli eventi di sospensione e ripresa dell’applicazione come mostrato in questo esempio:

import { 
  NativeModules
} from 'react-native';
let DeviceEvents = NativeModules.DeviceEvents;

class App extends React.Component {
  componentDidMount() {
    this.onPauseListener = DeviceEvents.addListener('onPause', () => {
      console.warn('Suspending app...');
      // La tua logica di sospensione qui!
    });
    this.onResumeListener = DeviceEvents.addListener('onResume', () => {
      console.warn('Resuming app...');
      // La tua logica di ripresa qui!
    });
  }
  componentWillUnmount() {
    // E' importante stoppare i listener quando il componente
    // è distrutto da React.
    this.onPauseListener.remove();
    this.onResumeListener.remove();
  }
}

L’esempio riportato inizializza i Listener nella fase di creazione del componente e li distrugge nella fase di distruzione dello stesso. Nel momento in cui l’app va in pausa o viene ripresa successivamente alla sospensione, riceviamo notifica di questo cambio di stato attraverso il nostro modulo personalizzato.

Questa guida si basa sulla documentazione tecnica disponibile ai seguenti link:

Scrivi un commento

Commento