2017-12-30 9 views
0

In meiner Android-App verwende ich Firebase Cloud Messaging, um einige Daten an App zu senden.Firebase Cloud Messaging: Zugriff auf Benutzeroberflächenelemente in onMessageReceived()

Wenn die Anwendung eine Nachricht durch onMessageReceived() empfängt, I zu überprüfen, ob ein derzeit MainActivity sichtbar ist (MainActivity die aktuell sichtbaren MainActivity eine statische Referenz hat), und wenn die Aktivität sichtbar ist, mache ich einige Modifikationen auf die Aktivität.

Da onMessageReceived() nicht im Haupt-Thread aufgerufen wird, verwende ich eine Handler, um den Code im Haupt-Thread auszuführen.

@Override 
public void onMessageReceived(final RemoteMessage remoteMessage) { 
    Handler handler = new Handler(Looper.getMainLooper()); 
    handler.post(new Runnable() { 
     //Access UI 
    }); 
} 

Ist etwas falsch mit diesem Ansatz? Falls nicht, gibt es andere Möglichkeiten, die aktuell sichtbare Benutzeroberfläche zu aktualisieren, wenn eine Cloud-Nachricht empfangen wird?

+2

Sie können mit der empfangenen Nachricht eine lokale Übertragung an die Aktivität senden und dort einige Änderungen vornehmen. –

Antwort

0

Sie sollten vermeiden, direkten Code in onMessageReceived() für UI-Änderungen in einer bestimmten Aktivität zu schreiben. Sie können es über lokale Rundfunkempfänger kanalisieren.

Wenn Sie dazu neigen, Code direkt in der onMessageReceived() schreiben Ihre FirebaseMessagingService Klasse wird überladen werden. Zum Beispiel, wenn Sie 4 verschiedene Arten von Benachrichtigungsdaten haben und jede Daten eine andere Aktivität erfordern. Dann wird Ihr Code wie folgt aussehen:

@Override 
public void onMessageReceived(final RemoteMessage remoteMessage) { 
    if(remoteMessage.getData() != null 
     && remoteMessage.getData().containsKey("notification_type")){ 
     switch(remoteMessage.getData().containsKey("notification_type")){ 
      case "type1": 
       Handler handler = new Handler(Looper.getMainLooper()); 
       handler.post(new Runnable() { 
        //Access UI for some activity 
        . 
        . 
        . 
       }); 
       break; 
      case "type2": 
       Handler handler = new Handler(Looper.getMainLooper()); 
       handler.post(new Runnable() { 
        //Access UI for some activity 
        . 
        . 
        . 
       }); 
       break; 
      case "type3": 
       Handler handler = new Handler(Looper.getMainLooper()); 
       handler.post(new Runnable() { 
        //Access UI for some activity 
        . 
        . 
        . 

       }); 
       break; 
      case "type4": 
       Handler handler = new Handler(Looper.getMainLooper()); 
       handler.post(new Runnable() { 
        //Access UI for some activity 
        . 
        . 
        . 

       }); 
       break; 

     } 
    } 

} 

Alternativ, wenn Sie lokale Broadcast verwenden dann Ihr Code wird viel mehr modular aufgebaut und organisiert. Ihr Code wird wie folgt aussehen:

@Override 
public void onMessageReceived(final RemoteMessage remoteMessage) { 
    if(remoteMessage.getData() != null 
     && remoteMessage.getData().containsKey("notification_type")){ 
     Intent intent = new Intent(); 
     intent.putExtra("body",messageBody); // Put info that you want to send to the activity 
     switch(remoteMessage.getData().containsKey("notification_type")){ 
      case "type1": 
       intent.setAction("ACTION_1") // For activity1 
       break; 
      case "type2": 
       intent.setAction("ACTION_2") //For activity2 
       break; 
      case "type3": 
       intent.setAction("ACTION_3") //For activity3 
       break; 
      case "type4": 
       intent.setAction("ACTION_4") //For activity4 
       break; 
     } 
     sendBroadcast(intent); 
    } 

} 

Und Ihre Aktivität (zB tätigkeit1.) Wird wie folgt aussehen: privaten BroadcastReceiver mReceiver;

Laut mir wird dies Ihnen helfen, Ihre UI-Änderungen innerhalb der Aktivität selbst zu codieren und führt Sie zu einem besseren Code-Management.

Ich hoffe, es ist nützlich!

Verwandte Themen