Autore Topic: Come passare un Handler ad un Remote Service  (Letto 1274 volte)

Offline vsibilla

  • Nuovo arrivato
  • *
  • Post: 10
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Arkos 70 Internet Tablet
  • Play Store ID:
    Vuesse
  • Sistema operativo:
    Mac OS X 10.6
Come passare un Handler ad un Remote Service
« il: 11 Marzo 2011, 15:28:12 CET »
0
Salve a tutti,

prima di tutto vorrei complimentarmi con tutti voi, ottimo forum e bellissimo sito.

Dopodiché volevo porre il seguente problema, ho realizzato un'applicazione per lo streaming audio. Ho realizzato un servizio con un'interfaccia AIDL dove carico l'oggetto MediaPlayer e gestisco i volumi, lo status...

Ora però vorrei gestire i callback del WorkerThread (il servizio) attraverso un handler verso il Main Thread (l'Activity principale). Come posso istanziare il servizio e passare l'handler? Oppure esiste un'altra possibilità?

Grazie a voi tutti!!!!
Valerio

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Come passare un Handler ad un Remote Service
« Risposta #1 il: 11 Marzo 2011, 16:32:23 CET »
0
Io per gestirmi le callback da un servizio remoto ho utilizzato la classe RemoteCallbackList. Permette di gestire la registrazione di listener da parte dei client che si collegano al servizio e gestisce anche il fatto che al momento dell'invocazione il processo che ha invocato il listener potrebbe non essere più attivo.


Offline vsibilla

  • Nuovo arrivato
  • *
  • Post: 10
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Arkos 70 Internet Tablet
  • Play Store ID:
    Vuesse
  • Sistema operativo:
    Mac OS X 10.6
Re:Come passare un Handler ad un Remote Service
« Risposta #2 il: 11 Marzo 2011, 16:42:01 CET »
0
Ti ringrazio Ricky, hai uno snippet da potermi postare?
grazie ancora Valerio

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Come passare un Handler ad un Remote Service
« Risposta #3 il: 11 Marzo 2011, 16:44:11 CET »
0

Offline vsibilla

  • Nuovo arrivato
  • *
  • Post: 10
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Arkos 70 Internet Tablet
  • Play Store ID:
    Vuesse
  • Sistema operativo:
    Mac OS X 10.6
Re:Come passare un Handler ad un Remote Service
« Risposta #4 il: 12 Marzo 2011, 15:23:19 CET »
0
Un consiglio, ma secondo te per gestire uno streaming audio è meglio usare un Service come sto facendo io ora oppure usare un Thread all'interno dell'Activity principale?

Dubbio amletico..... :)

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Come passare un Handler ad un Remote Service
« Risposta #5 il: 12 Marzo 2011, 15:54:31 CET »
0
Se ti serve che lo streaming continui anche se l'activity non è più visibile ti serve un Service (che al suo interno comunque deve utilizzare dei thread).

Offline vsibilla

  • Nuovo arrivato
  • *
  • Post: 10
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Arkos 70 Internet Tablet
  • Play Store ID:
    Vuesse
  • Sistema operativo:
    Mac OS X 10.6
Re:Come passare un Handler ad un Remote Service
« Risposta #6 il: 12 Marzo 2011, 16:04:27 CET »
0
Si, ovviamente deve funzionare anche ad Activity chiuso. E proprio per questo motivo avevo deciso di usare un servizio AIDL, non a caso ho implementato una serie di metodi che vado a richiamare:

interface IStreamingService {
  void setVolume(float volume);
  void playStreaming(String address);
  void stopStreaming();
  boolean isPlaying();
  void fadeOut();
  void fadeIn();
  String status();
}

ma come ti dicevo vorrei visualizzare sull'Activity gli status del MediaPlayer. Sinceramente ho letto il codice che mi avevi postato (che avevo già intravisto) ma non credo di riuscire a "interpretarlo" in poco tempo. Hai qualcos'altro da postarmi di più smart?  :-P

Valerio

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Come passare un Handler ad un Remote Service
« Risposta #7 il: 12 Marzo 2011, 16:21:36 CET »
0
Non ho ben capito qual'è il tuo problema.
Come mostra l'esempio tu puoi registrare delle callback remote e invocarle quando ti serve. Effettivamente l'esempio che ti ho linkato è un pochino contorno ma con un po' di pazienza capisci. Purtroppo non posso postarti il mio codice perchè dovrei ripulirmi e non ho troppo tempo per farlo...

Offline vsibilla

  • Nuovo arrivato
  • *
  • Post: 10
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Arkos 70 Internet Tablet
  • Play Store ID:
    Vuesse
  • Sistema operativo:
    Mac OS X 10.6
Re:Come passare un Handler ad un Remote Service
« Risposta #8 il: 12 Marzo 2011, 16:23:20 CET »
0
Mi stampo il codice e me lo studio con calma...
grazie lo stesso Ricky :)

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Come passare un Handler ad un Remote Service
« Risposta #9 il: 12 Marzo 2011, 16:31:44 CET »
+1
Comunque dall'esempio devi concentrare la tua attenzione su questo metodo, che dove le callbacks vengono invocate (nota che è un ciclo perchè più processi idealmente potrebbero averla registrata):

Codice (Java): [Seleziona]
    /**
     * Our Handler used to execute operations on the main thread.  This is used
     * to schedule increments of our value.
     */

    private final Handler mHandler = new Handler() {
        @Override public void handleMessage(Message msg) {
            switch (msg.what) {

                // It is time to bump the value!
                case REPORT_MSG: {
                    // Up it goes.
                    int value = ++mValue;

                    // Broadcast to all clients the new value.
                    final int N = mCallbacks.beginBroadcast();
                    for (int i=0; i<N; i++) {
                        try {
                            mCallbacks.getBroadcastItem(i).valueChanged(value);
                        } catch (RemoteException e) {
                            // The RemoteCallbackList will take care of removing
                            // the dead object for us.
                        }
                    }
                    mCallbacks.finishBroadcast();

                    // Repeat every 1 second.
                    sendMessageDelayed(obtainMessage(REPORT_MSG), 1*1000);
                } break;
                default:
                    super.handleMessage(msg);
            }
        }
    };

Questo è invece come il client dichiara la sua callback:
Codice (Java): [Seleziona]
        private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub() {
            /**
             * This is called by the remote service regularly to tell us about
             * new values.  Note that IPC calls are dispatched through a thread
             * pool running in each process, so the code executing here will
             * NOT be running in our main thread like most other things -- so,
             * to update the UI, we need to use a Handler to hop over there.
             */

            public void valueChanged(int value) {
                mHandler.sendMessage(mHandler.obtainMessage(BUMP_MSG, value, 0));
            }
        };

Questa è l'implementazione dell'interfaccia remota
Codice (Java): [Seleziona]
    private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
        public void registerCallback(IRemoteServiceCallback cb) {
            if (cb != null) mCallbacks.register(cb);
        }
        public void unregisterCallback(IRemoteServiceCallback cb) {
            if (cb != null) mCallbacks.unregister(cb);
        }
    };

e questa è l'aidl del listener (che devi andare a cercare su google perchè on è inclusa nell'esempio):
Codice (Java): [Seleziona]
/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package com.example.android.apis.app;

/**
 * Example of a callback interface used by IRemoteService to send
 * synchronous notifications back to its clients.  Note that this is a
 * one-way interface so the server does not block waiting for the client.
 */

oneway interface IRemoteServiceCallback {
    /**
     * Called when the service has a new value for you.
     */

    void valueChanged(int value);
}

Buon lavoro ;)