Page 160
__rendered_path__11
Proyecto Fin de Carrera
Desarrollo de aplicaciones para dispositivos móviles sobre la plataforma Android de Google
producido y que existe disponible una respuesta del servidor que puede ser leída y
procesada.
Estas comunicaciones han sido omitidas en el apartado 4.2.18 para centrar la atención
del lector en el funcionamiento de un elemento Service, pero existen. Android permite
cierto grado de comunicación entre una Activity y un Service lanzado por esta. Sin
embargo, la comunicación en el otro sentido, tal y como se desea aquí, es algo más
complejo y requiere el uso de interfaces remotas.
Una interfaz remota representa un mecanismo mediante el cual dos procesos separados
pueden utilizar métodos declarados en el otro proceso. Cada uno de los extremos
desconoce la implementación del otro, simplemente conoce a través de una interfaz qué
__rendered_path__11
métodos se ofrecen, pudiendo utilizarlos como si de cualquier otra clase local se tratase.
Algunas tecnologías de interfaces remotas más utilizados son RMI de Java o CORBA.
Android también cuenta con su propio mecanismo de interfaces remotas.
Antes de usar este tipo de comunicaciones en Android, es necesario realizar los
siguientes pasos:
1. Declarar la interfaz remota mediante el lenguaje AIDL (Android Interface
Definition Language). La declaración se realiza con una sintaxis muy básica e
incluye los nombres de los métodos, los parámetros que éstos aceptan y los
posibles valores devueltos. Con esta declaración se genera un resguardo o stub
para ser utilizado por el otro extremo.
2. Implementar dicha interfaz.
3. Obtener el objeto remoto que permita el acceso a los métodos declarados.
Declaración de las interfaces con AIDL y obtención de los stubs
El lenguaje AIDL de Android permite poder declarar interfaces remotas, generando
además un resguardo para que el extremo que las va utilizar pueda conocer su
naturaleza, aunque ignore su implementación. AIDL consiste en una simplísima sintaxis
que se limita a anunciar métodos y tipos de datos básicos, además de tipos de cualquier
clase perteneciente al paquete actual.
La clase Update necesita comunicar a ContactMap tanto el momento previo a la
conexión con el servidor como el momento inmediatamente posterior, para que dicha
clase puede escribir y leer los correspondientes documentos XML. Es decir,
ContactMap necesita ofrecer dos métodos remotos a los que Update pueda acceder:
notifyPreConnection(): donde se escribirá la petición.
__rendered_path__98
notifyPostConnection(): donde se leerá la respuesta.
__rendered_path__98
Jaime Aranaz Tudela
160
Ingeniería en Informática

Page 161
__rendered_path__11
Proyecto Fin de Carrera
Desarrollo de aplicaciones para dispositivos móviles sobre la plataforma Android de Google
Para que la clase Update pueda invocar estos métodos implementados en
ContactMap, ha de tener un objeto que represente la interfaz remota de ContactMap.
Se concluye, por tanto, que Update también ha de ofrecer otros métodos remotos que
permitan a ContactMap pasarle un instancia de su interfaz remota con la que pueda
invocar a sus métodos, es decir, hacer lo que se denomina callback. Update deberá
implementar, pues, los siguientes métodos remotos:
register(): guarda un objeto de la interfaz remota.
__rendered_path__32
unRegister(): elimina un objeto de la interfaz remota.
__rendered_path__32
La pregunta que puede surgir ahora es que si Update necesita tener una instancia de la
interfaz remota de ContactMap y registrarla para acceder a ella, ¿por qué a la inversa
__rendered_path__11
no se realiza el mismo proceso?; es decir, por qué ContactMap no necesita tener una
instancia de la interfaz remota de Update y, por tanto, registrarla igualmente. La
respuesta es que ContactMap sí necesita, como es lógico, una instancia de la interfaz
remota de Update a la que pretende acceder, pero no necesita registrarla porque la
obtiene automáticamente gracias al método bindService(). Esto se detalla más
adelante. Como se ha dicho, es más simple comunicar una Activity con su Service que a
la inversa.
Una vez conocidas las interfaces que se necesitan, el primer paso es declararlas
formalmente a través de AIDL. El siguiente código muestra la declaración de la interfaz
remota de ContactMap, llamada IRemoteCallback. En ella, el método
notifyPreConnection() devuelve un valor string, que consistirá en la petición
XML que se ha de enviar al servidor. Por su parte, el método
notifyPostConnection() recibe como parámetro otro tipo string que representa la
respuesta XML recibida desde el servidor.
__rendered_path__93
__rendered_path__93
package com.android.contactmap;
__rendered_path__94
__rendered_path__93
__rendered_path__93
interface IRemoteCallback {
__rendered_path__95
__rendered_path__95
String notifyPreConnection();
__rendered_path__97
void notifyPostConnection(String data);
__rendered_path__97
__rendered_path__99
}
__rendered_path__99
__rendered_path__99
__rendered_path__99
Código 63. Interfaz remota IRemoteCallback
__rendered_path__97
__rendered_path__97
__rendered_path__99
A continuación se muestra la interfaz remota implementada en la clase Update, que
__rendered_path__99
recibe el nombre de IRemoteRegister. Los métodos register() y unRegister()
__rendered_path__99
únicamente guardan y eliminan, respectivamente, una instancia de la interfaz remota
__rendered_path__99
IRemoteCallback.
__rendered_path__99
Jaime Aranaz Tudela
161
__rendered_path__99__rendered_path__99__rendered_path__99__rendered_path__97__rendered_path__97__rendered_path__93__rendered_path__93__rendered_path__94__rendered_path__93__rendered_path__93__rendered_path__108__rendered_path__108
Ingeniería en Informática

Page 162
__rendered_path__11
Proyecto Fin de Carrera
Desarrollo de aplicaciones para dispositivos móviles sobre la plataforma Android de Google
__rendered_path__14
__rendered_path__14
package com.android.contactmap;
__rendered_path__15
import com.android.contactmap.IRemoteCallback;
__rendered_path__14
__rendered_path__14
interface IRemoteRegister {
__rendered_path__16
__rendered_path__16
void register(IRemoteCallback regService);
__rendered_path__18
void unRegister(IRemoteCallback regService);
__rendered_path__18
__rendered_path__20
}
__rendered_path__20
__rendered_path__18
__rendered_path__18
Código 64. Interfaz remota IRemoteRegister
__rendered_path__11__rendered_path__23
__rendered_path__23
__rendered_path__23
Estas declaraciones deben ser guardadas en ficheros con el mismo nombre que el de la
__rendered_path__23
interfaz y con la extensión “.aidl”. Si se está trabajando con el plug-in de Eclipse, el
__rendered_path__18
simple hecho de colocarlas en el mismo proyecto donde van a ser utilizadas hará que se
__rendered_path__18
generen de forma automática dos ficheros Java, uno por cada interfaz, que representan
__rendered_path__23
el resguardo o stub que el otro extremo debe conocer para poder utilizarlas. En este
__rendered_path__23
caso, como ambos extremos ContactMap y Update están en el mismo proyecto, no
__rendered_path__23
hace falta trasladar ninguno de los resguardos.
__rendered_path__23
__rendered_path__23
Implementación de las interfaces
__rendered_path__23
__rendered_path__30__rendered_path__32
Tras haber declarado las interfaces con el lenguaje AIDL, el siguiente paso es
__rendered_path__30__rendered_path__32
implementar los métodos declarados en ellas. La interfaz IRemoteCallback se
__rendered_path__31
corresponde con las llamadas que hará la clase Update a la clase ContactMap para
__rendered_path__30
avisarle tanto de que va a conectar con el servidor y necesita una petición, como que ha
__rendered_path__30
terminado dicha conexión y ya dispone de una respuesta.
Para implementar la interfaz IRemoteCallback en la clase ContactMap se declara
un nuevo atributo de este tipo y se construyen los dos métodos anunciados. En el
Código 65 se expone la implementación realizada.
__rendered_path__14
__rendered_path__83__rendered_path__14
public class ContactMap extends MapActivity {
__rendered_path__15
__rendered_path__14
// Lista de contactos
__rendered_path__14
public ArrayList<Friend> mFriendList = new ArrayList<Friend>();
__rendered_path__32
// Controlador del localizador GPS
__rendered_path__32
private LocationManager mLocation = null;
__rendered_path__85
// Gestor de intercambios con XML
__rendered_path__23
private XMLExchange mXmlExchange = new XMLExchange();
__rendered_path__23
__rendered_path__92
__rendered_path__18
__rendered_path__18
Jaime Aranaz Tudela
162
__rendered_path__85__rendered_path__23__rendered_path__23__rendered_path__85__rendered_path__23__rendered_path__23__rendered_path__85__rendered_path__23__rendered_path__23__rendered_path__85__rendered_path__23__rendered_path__23__rendered_path__92__rendered_path__18__rendered_path__18__rendered_path__85__rendered_path__23__rendered_path__23__rendered_path__118__rendered_path__120__rendered_path__120__rendered_path__118__rendered_path__120__rendered_path__120__rendered_path__83__rendered_path__14__rendered_path__14__rendered_path__15__rendered_path__14__rendered_path__14__rendered_path__32__rendered_path__32
Ingeniería en Informática

Page 163
__rendered_path__11
Proyecto Fin de Carrera
Desarrollo de aplicaciones para dispositivos móviles sobre la plataforma Android de Google
__rendered_path__14
__rendered_path__12__rendered_path__14
__rendered_path__15
private IRemoteCallback.Stub mCallback = new IRemoteCallback.Stub() {
__rendered_path__14
__rendered_path__14
public String notifyPreConnection() {
__rendered_path__16
__rendered_path__16
// Devolver petición XML
__rendered_path__17
return mXmlExchange.writeXMLUpdate(
__rendered_path__19
getContentResolver(),
__rendered_path__19
(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE),
__rendered_path__20
mLocation.getLastKnownLocation(LocationManager.GPS_PROVIDER));
__rendered_path__27
__rendered_path__27
}
__rendered_path__28
__rendered_path__11__rendered_path__30
public void notifyPostConnection(String data) {
__rendered_path__30
__rendered_path__20
// Procesar respuesta XML
__rendered_path__27
mXmlExchange.readXMLUpdate(
__rendered_path__27
data, mFriendList, getContentResolver());
__rendered_path__20
__rendered_path__27
}
__rendered_path__27
};
__rendered_path__28
__rendered_path__30
}
__rendered_path__30
__rendered_path__38
__rendered_path__44
Código 65. Implementación de la interfaz IRemoteCallback
__rendered_path__44
__rendered_path__28
__rendered_path__30
Tal y como se ve en el Código 65, el método notifyPreConnection() utiliza la
__rendered_path__30
clase XMLExchange para construir un documento XML que represente una petición
__rendered_path__28
válida, donde se informe al servidor de la posición del usuario y se solicite las
__rendered_path__30
posiciones de los contactos. Por el contrario, el método notifyPostConnection()
__rendered_path__30
usa también dicha clase pero para leer la respuesta XML recibida del servidor, donde se
__rendered_path__38
encontrará la información de localización de los contactos.
__rendered_path__44
__rendered_path__44
Seguidamente, se muestra la implementación de la interfaz IRemoteRegister en la
__rendered_path__28
clase Update.
__rendered_path__30
__rendered_path__30
__rendered_path__20
public class Update extends Service{
__rendered_path__27
__rendered_path__27
// Lista con interfaces remotas
__rendered_path__20
__rendered_path__27
private RemoteCallbackList<IRemoteCallback> mCallbacks =
__rendered_path__27
new RemoteCallbackList<IRemoteCallback>();
__rendered_path__28
__rendered_path__30
private IRemoteRegister.Stub mRegister = new IRemoteRegister.Stub(){
__rendered_path__30
__rendered_path__20
public void register(IRemoteCallback interface) {
__rendered_path__27
// Guardar interfaz remota
__rendered_path__27
if (interface!= null) mCallbacks.register(interface);
__rendered_path__20
}
__rendered_path__27
Jaime Aranaz Tudela
163
__rendered_path__27__rendered_path__20__rendered_path__27__rendered_path__27__rendered_path__28__rendered_path__30__rendered_path__30__rendered_path__20__rendered_path__27__rendered_path__27__rendered_path__20__rendered_path__27__rendered_path__27__rendered_path__28__rendered_path__30__rendered_path__30__rendered_path__38__rendered_path__44__rendered_path__44__rendered_path__28__rendered_path__30__rendered_path__30__rendered_path__77__rendered_path__79__rendered_path__79__rendered_path__80__rendered_path__79__rendered_path__79__rendered_path__81__rendered_path__81__rendered_path__110__rendered_path__14__rendered_path__14__rendered_path__15__rendered_path__14__rendered_path__14__rendered_path__117__rendered_path__117__rendered_path__20__rendered_path__27__rendered_path__27__rendered_path__28__rendered_path__30__rendered_path__30__rendered_path__38__rendered_path__44__rendered_path__44__rendered_path__28__rendered_path__30__rendered_path__30__rendered_path__28__rendered_path__30__rendered_path__30__rendered_path__38__rendered_path__44__rendered_path__44__rendered_path__28__rendered_path__30__rendered_path__30__rendered_path__20__rendered_path__27__rendered_path__27__rendered_path__20__rendered_path__27__rendered_path__27__rendered_path__28__rendered_path__30__rendered_path__30__rendered_path__20__rendered_path__27__rendered_path__27__rendered_path__151__rendered_path__14__rendered_path__14__rendered_path__15__rendered_path__14__rendered_path__14__rendered_path__153__rendered_path__153
Ingeniería en Informática

Page 164
__rendered_path__11
Proyecto Fin de Carrera
Desarrollo de aplicaciones para dispositivos móviles sobre la plataforma Android de Google
__rendered_path__14
__rendered_path__12__rendered_path__14
public void unRegister(IRemoteCallback interface) {
__rendered_path__15
// Eliminar interfaz remota
__rendered_path__14
if (interface!= null) mCallbacks.unregister(interface);
__rendered_path__14
}
__rendered_path__16
};
__rendered_path__16
}
__rendered_path__17
__rendered_path__23
Código 66. Implementación de la interfaz IRemoteRegister
__rendered_path__23
__rendered_path__17
__rendered_path__23
Antes de implementar la interfaz, se declara una instancia de la clase
__rendered_path__23
RemoteCallbackList, perteneciente al paquete android.os. Esta clase permite
__rendered_path__11__rendered_path__27
manejar más fácilmente un conjunto de interfaces remotas especialmente pensadas para
__rendered_path__35
hacer callback desde un Service. En el caso aquí explicado, a priori solamente habrá un
__rendered_path__35
único elemento en esta lista: la instancia de la interfaz IRemoteCallback.
__rendered_path__17
__rendered_path__23
Los métodos remotos register() y unRegister() simplemente añaden o eliminan
__rendered_path__23
una interfaz remota a la lista. De esta forma, una vez está incluida en dicha lista, se
__rendered_path__37
puede acceder sin mayor complicación a los métodos remotos ofrecidos por esa interfaz.
__rendered_path__39
__rendered_path__39
Utilización de las interfaces
__rendered_path__40
__rendered_path__14__rendered_path__42
Llegado este punto, las interfaces remotas ya han sido declaradas mediante AIDL, se ha
__rendered_path__14__rendered_path__42
generado automáticamente su stub o resguardo y además se han implementado los
__rendered_path__15
métodos que cada interfaz ofrece: la interfaz IRemoteCallback está implementada
__rendered_path__14
dentro de la clase ContactMap, y la interfaz IRemoteRegister lo está en la clase
__rendered_path__14
Update. Ahora es necesario proporcionar a cada clase una instancia de la interfaz
remota que necesita, esto es, ContactMap precisa de una instancia de
IRemoteRegister y Update requiere una instancia de IRemoteCallback.
Para ofrecer a ContactMap una instancia de IRemoteRegister es necesario utilizar
el método bindService() de la clase Context. . La clase Service tiene también un
ciclo de vida bien definido, es decir, cuenta con métodos como onCreate(),
onStart(), onDestroy(), etc. Cuando se lanza un elemento Service, por defecto este
es independiente al ciclo de vida de la Activity que lo ha lanzado, lo que implica que el
Service seguirá ejecutándose aunque la Activity que lo ha lanzado muera, y solamente
finalizará cuando la Activity lo haga de forma explícita.
En esta situación no se desea que el Service sea independiente. Por un lado, interesa
vincular el ciclo de vida de la clase ContactMap y la clase Update para que cuando la
aplicación ContactMap finalice, la conexión periódica con el servidor también lo haga;
por otra, la utilización de bindService() va a proporcionar a la clase ContactMap
una instancia de la interfaz remota que necesita, IRemoteRegister.
Jaime Aranaz Tudela
164
Ingeniería en Informática

Page 165
__rendered_path__11
Proyecto Fin de Carrera
Desarrollo de aplicaciones para dispositivos móviles sobre la plataforma Android de Google
En el siguiente código, el Código 67, se muestra al lector cómo se utiliza
bindService() para poder lanzar correctamente el servicio Update de la forma que
aquí interesa.
__rendered_path__23
__rendered_path__21__rendered_path__23
public class ContactMap extends MapActivity {
__rendered_path__24
__rendered_path__23
@Override
__rendered_path__23
public void onCreate(Bundle savedInstanceState) {
__rendered_path__25
__rendered_path__25
// (...)
__rendered_path__26
__rendered_path__11__rendered_path__33
// Wi-Fi disponible
__rendered_path__33
if (wifiEnabled==true){
__rendered_path__26
__rendered_path__33
// Vincular el Service y la Activity actual
__rendered_path__33
bindService(new Intent(IRemoteRegister.class.getName()),
__rendered_path__26
mConnection, Context.BIND_AUTO_CREATE);
__rendered_path__33
__rendered_path__33
// Crear un Intent asociado a la clase Update
__rendered_path__38
Intent UpdateService = new Intent(this, Update.class);
__rendered_path__44
__rendered_path__44
// Lanzar Service
__rendered_path__26
this.startService(UpdateService);
__rendered_path__33
__rendered_path__33
// Wi-Fi no disponible
__rendered_path__26
}else{
__rendered_path__33
__rendered_path__33
// Lanzar aviso
__rendered_path__38
// Obtener localizaciones desde SQLite
__rendered_path__44
__rendered_path__44
}
__rendered_path__26
__rendered_path__33
// (...)
__rendered_path__33
}
__rendered_path__26
}
__rendered_path__33
__rendered_path__33
__rendered_path__38
Código 67. Lanzar el Service Update usando interfaces remotas
__rendered_path__44
__rendered_path__44
__rendered_path__56
Este código es íntimamente similar al mostrado en el Código 61, salvo que antes de
__rendered_path__60
lanzar el servicio con startService() se utiliza el método bindServicer(),
__rendered_path__60
vinculando así la clase ContactMap y la clase Update. Se pueden apreciar tres
__rendered_path__38
parámetros en este método:
__rendered_path__44
__rendered_path__44
Un objeto de la clase Intent.
__rendered_path__26
Un objeto de la clase ServiceConnection, llamado aquí mConnection.
__rendered_path__33
Un flag de valor Context.BIND_AUTO_CREATE para la creación del elemento
__rendered_path__33
Service.
__rendered_path__26
__rendered_path__33
Jaime Aranaz Tudela
165
__rendered_path__33__rendered_path__38__rendered_path__44__rendered_path__44__rendered_path__26__rendered_path__33__rendered_path__33__rendered_path__26__rendered_path__33__rendered_path__33__rendered_path__26__rendered_path__33__rendered_path__33__rendered_path__38__rendered_path__44__rendered_path__44__rendered_path__26__rendered_path__33__rendered_path__33__rendered_path__26__rendered_path__33__rendered_path__33__rendered_path__38__rendered_path__44__rendered_path__44__rendered_path__56__rendered_path__60__rendered_path__60__rendered_path__38__rendered_path__44__rendered_path__44__rendered_path__38__rendered_path__44__rendered_path__44__rendered_path__56__rendered_path__60__rendered_path__60__rendered_path__38__rendered_path__44__rendered_path__44__rendered_path__26__rendered_path__33__rendered_path__33__rendered_path__26__rendered_path__33__rendered_path__33__rendered_path__38__rendered_path__44__rendered_path__44__rendered_path__26__rendered_path__33__rendered_path__33__rendered_path__21__rendered_path__23__rendered_path__23__rendered_path__24__rendered_path__23__rendered_path__23__rendered_path__25__rendered_path__25__rendered_path__128__rendered_path__128__rendered_path__128
Ingeniería en Informática

Page 166
__rendered_path__11
Proyecto Fin de Carrera
Desarrollo de aplicaciones para dispositivos móviles sobre la plataforma Android de Google
Con respecto al primer parámetro de bindServicer(), el lector ya sabrá que un Intent
siempre representa una acción que se desea realizar. Al crear un Intent, o bien se
especifica qué acción se desea llevar a cabo utilizando alguna de las constantes que
ofrece Android (ver los apartados 4.2.15 ó 4.2.16) o bien se especifica directamente la
clase que se quiere lanzar (repásense los casos descritos en los apartados 4.2.14 ó
4.2.17). Aquí se opta por el segundo caso. Lo que se está diciendo a través del Intent es
que se desea ejecutar la interfaz IRemoteRegister. Ya que la clase
IRemoteRegister presente en el proyecto no es una clase ejecutable, sino un simple
stub o resguardo, debe existir algún otro elemento que indique explícitamente que puede
hacerse cargo de Intents de ese tipo. Dicho esto, se comprederá ahora la necesidad de
que en el fichero “AndroidManifest.xml”, el Service ya declarado Update anuncie
ahora que puede atender este tipo de Intents:
__rendered_path__11
__rendered_path__55
__rendered_path__53__rendered_path__55
<service android:name=".Update">
__rendered_path__56
<intent-filter>
__rendered_path__55
<action android:name="com.android.contactmap.IRemoteRegister" />
__rendered_path__55
</intent-filter>
__rendered_path__57
</service>
__rendered_path__57
__rendered_path__58
__rendered_path__60
Código 68. Declaración en el manifiesto de los Intents para el Service Update
__rendered_path__60
__rendered_path__61
__rendered_path__63
Con la etiqueta <intent-filter> cualquier componente de una aplicación Android
__rendered_path__63
puede anunciar que es capaz de hacerse cargo de unos determinados Intents. De hecho,
__rendered_path__61
esta etiqueta es consultada por Android una por una en las aplicaciones instaladas
__rendered_path__63
cuando alguien lanza un Intent, a fin de encontrar a la aplicación más adecuada para
__rendered_path__63
hacerse cargo. Así pues, cuando alguien lance un Intent asociado a IRemoteRegister,
__rendered_path__61
la clase Update se hará cargo de ello.
__rendered_path__63
__rendered_path__63
El segundo parámetro de bindService() es un objeto de la clase
__rendered_path__58
ServiceConnection. Esta clase pertenece al paquete android.content y es en
__rendered_path__60
realidad una interfaz que debe ser implementada por el desarrollador. Ya que
__rendered_path__60
bindService() permite vincular al Service y a la Activity, debe existir un objeto que
__rendered_path__53
monitorice cuál es el estado del Service. Este es el cometido del objeto
__rendered_path__55__rendered_path__57
ServiceConnection. En concreto, ofrece dos métodos: onServiceConnected() y
__rendered_path__55__rendered_path__57
onServiceDesconnected(). Como se podrá intuir, el primero es llamado cuando el
__rendered_path__56
Service y la Activity se conectan, mientras que el segundo lo hace cuando se
__rendered_path__55
desconectan.
__rendered_path__55
La llamada a bindService() invoca en el lado del componente Service un método
denominado onBind(). La finalidad de este método está enfocada casi en exclusiva a
la utilización con interfaces remotas, ya que su objetivo es devolver a la Activity un
objeto mediante el cual pueda comunicarse con el Service. Este objeto ha de ser una
instancia de la interfaz IRemoteRegister, tal y como se ve en el siguiente código.
Jaime Aranaz Tudela
166
Ingeniería en Informática

Page 167
__rendered_path__11
Proyecto Fin de Carrera
Desarrollo de aplicaciones para dispositivos móviles sobre la plataforma Android de Google
__rendered_path__15
__rendered_path__13__rendered_path__15
public class Update extends Service{
__rendered_path__16
__rendered_path__15
private IRemoteRegister.Stub mRegister = new IRemoteRegister.Stub(){
__rendered_path__15
__rendered_path__17
// Aquí se implementan los métodos register() y unRegister()
__rendered_path__17
__rendered_path__18
}
__rendered_path__25
__rendered_path__25
@Override
__rendered_path__26
public IBinder onBind(Intent intent) {
__rendered_path__28
__rendered_path__28
return mRegister;
__rendered_path__18
}
__rendered_path__11__rendered_path__25
__rendered_path__25
}
__rendered_path__35
__rendered_path__37
__rendered_path__37
Código 69. Método onBind() de la clase Update
__rendered_path__35
__rendered_path__37
__rendered_path__37
Así pues, la clase ContactMap, tras invocar al método bindService() y este al
__rendered_path__18
método onBind(), obtiene una instancia de la interfaz IRemoteRegister. Este
__rendered_path__25
objeto se recibe a través del método onServiceConnected(), que forma parte de la
__rendered_path__25
interfaz de ServiceConnection y debe ser implementado por el desarrollador. La
__rendered_path__35
finalidad de tener una instacia de IRemoteRegister, como se recordará, es permitir a
__rendered_path__37
la clase ContactMap registrar en la clase Update una instancia de
__rendered_path__37
IRemoteCallback, de forma que el círculo de comunicación ya quede cerrado.
__rendered_path__35
__rendered_path__37
__rendered_path__37
__rendered_path__35
public class ContactMap extends MapActivity {
__rendered_path__37
__rendered_path__37
// Interfaz remota de la clase Update
__rendered_path__18
private IRemoteRegister mService = null;
__rendered_path__25
__rendered_path__25
// Interfaz remota de la clase ContactMap
__rendered_path__35
private IRemoteCallback.Stub mCallback = new IRemoteCallback.Stub() {
__rendered_path__37
__rendered_path__37
// Aquí se implementan los método notifyPreConnection() y
__rendered_path__35
// notifyPostConnection()
__rendered_path__37
__rendered_path__37
};
__rendered_path__18
__rendered_path__25
private ServiceConnection mConnection = new ServiceConnection() {
__rendered_path__25
__rendered_path__26
public void onServiceConnected(ComponentName className,
__rendered_path__28
IBinder service) {
__rendered_path__28
__rendered_path__18
// Obtener instacia gracias al stub
__rendered_path__25
mService = IRemoteRegister.Stub.asInterface(service);
__rendered_path__25
__rendered_path__57
__rendered_path__15__rendered_path__59
Jaime Aranaz Tudela
167
__rendered_path__15__rendered_path__16__rendered_path__15__rendered_path__15__rendered_path__59__rendered_path__92__rendered_path__15__rendered_path__15__rendered_path__16__rendered_path__15__rendered_path__15__rendered_path__94__rendered_path__94__rendered_path__35__rendered_path__37__rendered_path__37__rendered_path__18__rendered_path__25__rendered_path__25__rendered_path__35__rendered_path__37__rendered_path__37__rendered_path__35__rendered_path__37__rendered_path__37__rendered_path__35__rendered_path__37__rendered_path__37__rendered_path__18__rendered_path__25__rendered_path__25__rendered_path__35__rendered_path__37__rendered_path__37__rendered_path__35__rendered_path__37__rendered_path__37__rendered_path__35__rendered_path__37__rendered_path__37__rendered_path__35__rendered_path__37__rendered_path__37__rendered_path__18__rendered_path__25__rendered_path__25__rendered_path__35__rendered_path__37__rendered_path__37__rendered_path__127__rendered_path__129__rendered_path__129__rendered_path__35__rendered_path__37__rendered_path__37__rendered_path__18__rendered_path__25__rendered_path__25__rendered_path__26__rendered_path__28__rendered_path__28__rendered_path__18__rendered_path__25__rendered_path__25__rendered_path__18__rendered_path__25__rendered_path__25__rendered_path__26__rendered_path__28__rendered_path__28__rendered_path__18__rendered_path__25__rendered_path__25__rendered_path__35__rendered_path__37__rendered_path__37__rendered_path__13__rendered_path__15__rendered_path__15__rendered_path__16__rendered_path__15__rendered_path__15__rendered_path__17__rendered_path__17
Ingeniería en Informática