6

Ok, soy nuevo en el desarrollo de Android y estoy intentando vincularme a un servicio para que pueda llamar a los métodos en el servicio una vez que se haya iniciado. La actividad y el servicio descritos a continuación son parte de la misma aplicación, por lo que no debería haber ningún problema, pero cada vez que ejecuto mi aplicación aparece el siguiente error:Excepción de Android ClassCast al vincular al servicio

java.lang.ClassCastException: android.os.BinderProxy

La línea de esto sucede en es:

LocalBinder binder = (LocalBinder) service; 

Mi código de actividad (simplificado es):

public class Main extends Activity { 

    boolean gpsBound = false; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
    } 

    /** Called whenever the activity is started. */ 
    @Override 
    protected void onStart() { 
     super.onStart(); 
     // Bind to GPSService 
     Intent i = new Intent(this, GPSService.class); 
    startService(i); 
    bindService(i, connection, Context.BIND_AUTO_CREATE); 
    } 

    /** service binding */ 
    private ServiceConnection connection = new ServiceConnection() { 

     public void onServiceConnected(ComponentName className, IBinder service) { 
      // After binding to GPSService get the instance of it returned by IBinder 
     LocalBinder binder = (LocalBinder) service; 
      gpsBound = true; 
     } 

     public void onServiceDisconnected(ComponentName className) { 
      gpsBound = false; 
     } 
    }; 

} 

Servicio:

public class GPSService extends Service { 

    @Override 
    public void onCreate() { 
      super.onCreate(); 
    } 

    @Override 
    public IBinder onBind(Intent i) { 
    // TODO Auto-generated method stub 
    return new LocalBinder<GPSService>(this); 
    } 


    /** 
    * Our implementation of LocationListener that handles updates given to us 
    * by the LocationManager. 
    */ 
    public class CustomLocationListener implements LocationListener { 

     DBHelper db; 

     CustomLocationListener() { 
      super(); 
     } 

    // Overridden methods here... 

    } 

} 

Y por último, mi LocalBinder:

/** 
* A generic implementation of Binder to be used for local services 
* @author Geoff Bruckner 12th December 2009 
* 
* @param <S> The type of the service being bound 
*/ 

public class LocalBinder<S> extends Binder { 
    private String TAG = "LocalGPSBinder"; 
    private WeakReference<S> mService; 


    public LocalBinder(S service){ 
     mService = new WeakReference<S>(service); 
    } 


    public S getService() { 
     return mService.get(); 
    } 
} 

entiendo el significado de la excepción ClassCast pero no puede entender qué hacer! Seguí el ejemplo en la documentación de google, pero todavía no funciona. ¿Alguien puede arrojar alguna luz sobre lo que podría estar causando esto?

¡Gracias de antemano!

Respuesta

3

LocalBinder pasado enServiceConnected tiene un argumento de tipo genérico, mientras que su variable local LocalBinder binder no tiene uno.

resolver este un modo u otro, ya sea eliminando el tipo genérico de la definición de LocalBinder, o añadiendo uno a su declaración de su carpeta variable local en onServiceConnected

class MyBoundService extends Service{ 
    private final IBinder mBinder = new MyBinder(); 

    @Override 
    public IBinder onBind(Intent intent) { 
     return mBinder; 
    } 

    public class MyBinder extends Binder{ 

     public void doStuff(){ 
      //Stuff 
     } 
     //More Binder Methods 
    } 
} 

class MyActivity extends Activity{ 
    private MyBinder mBinder; 

    @Override 
    protected void onStart(){ 
     Intent intent = new Intent(this, MyBoundService.class); 
     bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 
    } 

    @Override 
    protected void onStop(){ 
     unbindService(mConnection); 
    } 

    private ServiceConnection mConnection = new ServiceConnection() { 

     @Override 
     public void onServiceConnected(ComponentName className, IBinder service) { 
      mBinder = (TaskBinder) service; 
      mBound = true; 
     } 

     @Override 
     public void onServiceDisconnected(ComponentName arg0) { 
      mBound = false; 
     } 
    }; 

    private void doStuff(){ 
     if (mBound) 
      mBinder.doStuff(); 
    } 
} 

hay necesidad real de tocar el violín alrededor con referencias débiles y otras cosas. solo asegúrese de desvincular (no lo hice en la muestra)

Si desea invocar los métodos de servicio ASAP lo antes posible, simplemente realice llamadas enServiceConnected, después de configurar mBinder. de lo contrario, solo invoque desde otras devoluciones de llamada (eventos OnClick y otras cosas).

+0

Qué quiere decir gustaría: 'servicio LocalBinder aglomerante = (LocalBinder );' ¡Si es así, todavía da el mismo error! –

+0

Me estaba inclinando a sacar los genéricos por completo. Editaré en una muestra rápida de uso de un servicio enlazado que estoy escribiendo en este momento. –

+0

¡Tendré una oportunidad sin genéricos, pero si pudieras dar un ejemplo sería genial!Gracias, James –

3

Si está tratando de conectarse a un servicio local que sí, puede simplemente emitirlo. Sin embargo, si intenta vincularse a un servicio remoto (proceso separado) debe usar el método AIDL como se prescribe en este artículo.

http://developer.android.com/guide/components/aidl.html

+0

enlace ya no es válido. –

+0

Aquí está el nuevo enlace válido http://developer.android.com/guide/components/aidl.html – MrMaffen

32

atributo Borrar process en su AndroidManifest.xml de su servicio.

+2

Esa es la respuesta correcta. – Snicolas

+1

Curioso, ¿alguna razón detallada? –

+0

@ThomasDecaux Creo que es porque LocalBinder solo se puede usar siempre que el servicio se ejecute en el mismo proceso (local) que la aplicación. El atributo de proceso crea un proceso separado para que el servicio se ejecute y, por lo tanto, debe usar IPC para comunicarse con él. Durante el proceso de vinculación, Android le proporciona un BinderProxy para actuar como puente hacia el servicio, de modo que pueda crear instancias de sus clases de IPC (escritas en AIDL). http://stackoverflow.com/a/10610463/269876 –

4

Tenía el mismo error. Agregué el atributo android: process = ": process_description" en el manifiesto. Cuando se suma, su servicio se crea como proceso independiente y por lo tanto se obtiene instancia de binderProxy (De ahí la excepción de difusión clase)

Cuestiones relacionadas