41 votes

Moyen plus efficace de mise à jour de l'INTERFACE utilisateur de Service que les intentions?

J'ai actuellement un Service d'Android qui est un exemple de client de VOIP de sorte qu'il est à l'écoute pour des messages SIP et si il reçoit un il démarre une Activité à l'écran, avec les composants de l'INTERFACE utilisateur.

Ensuite, les messages SIP déterminer ce que l'Activité est à l'affichage sur l'écran. Par exemple, si un appel entrant, il affiche Répondre ou Rejeter ou un appel sortant, il affiche un écran de numérotation.

À la minute où je utiliser les Intentions de laisser l'Activité de savoir dans quel état elle doit afficher.

En voici un exemple:


        Intent i = new Intent();
        i.setAction(SIPEngine.SIP_TRYING_INTENT);
        i.putExtra("com.net.INCOMING", true);
        sendBroadcast(i);

        Intent x = new Intent();
        x.setAction(CallManager.SIP_INCOMING_CALL_INTENT);
        sendBroadcast(x);
        Log.d("INTENT SENT", "INTENT SENT INCOMING CALL AFTER PROCESSINVITE");

L'activité aura un récepteur de radiodiffusion inscrits pour ces intentions et passera son état selon la dernière volonté qu'il a reçu.

Exemple de code comme suit:


       SipCallListener = new BroadcastReceiver(){

            @Override
            public void onReceive(Context context, Intent intent) {
                    String action = intent.getAction(); 

                    if(SIPEngine.SIP_RINGING_INTENT.equals(action)){
                        Log.d("cda ", "Got RINGING action SIPENGINE");
                        ringingSetup();
                    }         

                    if(CallManager.SIP_INCOMING_CALL_INTENT.equals(action)){
                        Log.d("cda ", "Got PHONE RINGING action");
                        incomingCallSetup();
                    }  
            }
        };
        IntentFilter filter = new IntentFilter(CallManager.SIP_INCOMING_CALL_INTENT);
        filter.addAction(CallManager.SIP_RINGING_CALL_INTENT);
        registerReceiver(SipCallListener, filter);

Cela fonctionne toutefois, il semble qu'il n'est pas très efficace, les Intentions obtenez une diffusion à l'échelle du système et les Intentions avoir à feu pour les différents états qui semble comme il pourrait devenir inefficace la plus-je inclure ainsi que l'ajout de complexité.

Donc je me demandais si il existe un autre plus efficace et plus propre façon de le faire?

Est-il un moyen de garder les Intentions de radiodiffusion uniquement à l'intérieur d'une application?

Serait rappels être une meilleure idée? Si oui, pourquoi et en quoi devraient-elles être appliquées?

52voto

Rich Points 16818

J'ai l'habitude de sous-classe de l'Application et de laisser mon dans-app de communication passent par cette classe (ou d'avoir un médiateur appartenant à l'Application faire le travail...peu importe, l'Application étant le point d'entrée pour le service pour communiquer avec). J'ai une borne de service qui doit mettre à jour l'INTERFACE utilisateur ainsi (beaucoup plus simple que la vôtre, mais la même idée) et il raconte essentiellement l'application de son nouvel état et l'application peut ensuite transmettre cette information le long d'une façon ou d'une autre à l'actif de l'activité. Vous pouvez également maintenir un pointeur à l'actif de l'activité (si il n'y a plus d'un), et de prendre des décisions à savoir si ou de ne pas simplement mettre à jour l'activité en cours, la diffusion de son intention de lancer une activité différente, ignorer le message, etc. Je voudrais également sous-classe de l'Activité et de votre nouvelle activité de base de la classe de dire à l'Application qu'il est actuellement active dans onResume et qu'il est interrompu dans onPause (pour les cas où le service est exécuté en arrière-plan et les activités sont en pause).

EDIT:

En réponse à cette observation, voici plus de détails.

Votre application se compose actuellement de l'Activité dérivés et de Service-les classes dérivées pour la plupart. Fondamentalement, vous bénéficiez de fonctionnalités à partir d'une instance de l'androïde.app.La classe d'Application. Cela est déclaré dans le manifeste (par défaut) avec la ligne suivante:

<application android:icon="@drawable/icon" android:label="@string/app_name">

L'élément de l'application dans votre manifeste, ne pas utiliser android:nom de l'attribut, de sorte qu'il crée une instance de la valeur par défaut d'android.app.Application de classe pour représenter l'ensemble de vos contexte de l'application.

Dans mes applications, j'ai créer une sous-classe d'Application (ApplicationEx, par exemple) et je dis à mon application à travers le manifeste que c'est la classe à instancier comme MES contexte de l'application. Par exemple:

<application
    android:name="com.mycompany.myapp.app.ApplicationEx"
    android:icon="@drawable/app_icon"
    android:label="@string/app_name">

Je peux maintenant ajouter des méthodes à ApplicationEx d'activités et de services à utiliser pour communiquer. Il y a toujours une seule instance de votre application à l'échelle mondiale contexte, alors c'est votre point de départ, si quelque chose doit être globale pour votre application.

Un deuxième morceau de ceci est que, au lieu de dériver mes services et activités de Service et de l'Activité, j'ai créer une sous-classe de chacun avec une getAppContext méthode qui projette la valeur de retour de getcontexteapplication (qui existe déjà dans ces deux classes, car ils proviennent de Contexte) pour mon ApplicationEx classe.

Donc........

Tout cela étant dit, vous ajoutez un CurrentActivity propriété à votre ApplicationEx catégorie de type d'Activité (ou ActivityBase si vous sous-classe comme je le fais). Dans ActivityBase de la méthode onResume, vous passez vous-même à ApplicationEx pour définir CurrentActivity à cette activité. Maintenant, vous pouvez exposer des méthodes sur ApplicationEx de transmettre les informations directement à l'activité en cours au lieu de s'appuyer sur l'Intention de mécanismes.

C'est aussi clair que je peux le faire

2voto

Edmund Chang Points 151

Vous pouvez diffuser des intentions juste pour votre propre application et non pas à l'échelle du système avec LocalBroadcastManager:

De l'aide pour vous inscrire et envoyer des diffusions des Intentions aux objets locaux au sein de votre processus. C'est a un certain nombre d'avantages par rapport à l'envoi de diffusion mondiale avec sendBroadcast(Intention):

Vous savez que les données sont de radiodiffusion ne laissera pas votre application, afin de ne pas besoin de s'inquiéter à propos de la fuite de données privées.

Il n'est pas possible pour d'autres applications pour envoyer ces émissions à votre application, donc vous n'avez pas besoin de s'inquiéter d'avoir des trous de sécurité qu'ils peuvent exploiter.

Il est plus efficace que l'envoi d'une diffusion mondiale, à travers le système.

Cependant, je voudrais encore vous recommandons d'aller avec l'approche du Service et localement de liaison et de parler à travers le Gestionnaire lorsque nécessaire pour mettre à jour les composants de l'INTERFACE utilisateur pour plus d'efficacité.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X