2011-02-24 17 views
7

Tengo un servicio que está configurado para iniciarse en un proceso separado:pasando objeto personalizado al servicio de Android en diferentes procesos

<service android:name=".services.UploadService" 
      android:process=":UploadServiceProcess" /> 

Y puedo unir con éxito a él utilizando bindService(). Mi problema se produce cuando intento enviar un mensaje llamando Messenger.send():

service.send(Message.obtain(null, UploadService.MESSAGE_UPLOAD_REQUEST, uploadRequest)); 

donde uploadRequest es un objeto personalizado que implementa parcelable

 
public class UploadRequest implements Parcelable { 
    public File file; 
    public boolean deleteOnUpload;

public UploadRequest(File file, boolean deleteOnUpload) { 
    this.file = file; 
    this.deleteOnUpload = deleteOnUpload; 
} 

private UploadRequest(Parcel in) { 
    this.file = new File(in.readString()); 
} 

public int describeContents() { 
    return 0; 
} 

public void writeToParcel(Parcel dest, int flags) { 
    dest.writeString(this.file.getPath()); 
} 

public static final Parcelable.Creator<UploadRequest> CREATOR = new Parcelable.Creator<UploadRequest>() { 
    public UploadRequest createFromParcel(Parcel in) { 
     return new UploadRequest(in); 
    } 
    public UploadRequest[] newArray(int size) { 
     return new UploadRequest[size]; 
    } 
}; 

}

puse un punto de interrupción en mi handleMessage servicios, pero mi aplicación nunca llega al punto de ruptura. Sin embargo, si en lugar de usar mi objeto UploadRequest personalizado envié null, llego al punto de ruptura de handleMessage como era de esperar, pero obviamente no puedo hacer nada en ese momento. Comprobé que file.getPath() al llamar a writeToParcel devuelve una cadena no nula. Esto me lleva a creer que algo no funciona en mi clase UploadRequest, pero de google no veo nada malo en mi clase. ¿Algunas ideas?

Respuesta

13

La documentación de Message member obj dice:

un objeto arbitrario para enviar al destinatario . Al usar Messenger en , envíe el mensaje a través de los procesos; este solo puede ser no nulo si contiene un Parcelable de una clase de infraestructura (no , uno implementado por la aplicación). Para otra transferencia de datos use setData (Bundle). Tenga en cuenta que los objetos Parcelable aquí no son compatibles antes de con la versión FROYO.

Supongo que está viendo un problema porque está creando su propio parcelable que no está permitido al cruzar el límite del proceso. En cambio, tendrá que empaquetar su objeto en un paquete. Esto también significa que su objeto necesitará implementar Serializable pero no será necesario Parcelable.

+1

Gracias! Quizás la próxima vez voy a RTFM: D –

+1

¡Esto es realmente esotérico así que me siento bien aprendiendo algo también! –

3

intenté esto ahora.

Message.obj puede transferir una clase de infraestructura, como ContentValues.

y Message.SetData puede transferir un paquete a través de procesos y puede colocar cualquier objeto Parcelable en el paquete.

simplemente recuerde llamar a setClassLoader en paquete, cuando recibió el mensaje.

lado emisión

 Message localMsg = Message.obtain(); 
     localMsg.what = TPServiceConnection.MSG_REPLY_SERVICE_HELLO; 

     Bundle data = new Bundle(); 

     ContentValues cv = new ContentValues(); 
     cv.put("KEY", mRand.nextInt()); 
     data.putParcelable("KEY", cv); 

     TPServiceDataModal modal = new TPServiceDataModal(mRand.nextInt()); 
     data.putParcelable("KEY2", modal); 

     localMsg.setData(data); 

lado recepción

 Bundle data = msg.getData(); 
     data.setClassLoader(this.getClass().getClassLoader()); 

     Parcelable parcelable = data.getParcelable("KEY"); 
     if (parcelable instanceof ContentValues) { 
      ContentValues cv = (ContentValues) parcelable; 
      Log.d(TAG, "reply content: " + cv.getAsInteger("KEY")); 
     } 

     Parcelable parcelable2 = data.getParcelable("KEY2"); 
     if (parcelable2 instanceof TPServiceDataModal) { 
      TPServiceDataModal modal = (TPServiceDataModal) parcelable2; 
      Log.d(TAG, "reply modal: " + modal.mData); 
     } 

donde TPServiceDataModal es un calss parcelable.

+0

El punto clave es establecer el cargador de clases de nivel de aplicación en lugar del cargador de clases de framework. O bien, el objeto parcelable personalizado no puede desasignarse. –

Cuestiones relacionadas