javaandroidservice

java.lang.ClassCastException: android.os.BinderProxy cannot be cast to xxx$LocalBinder


I am implementing a service and have a wrapper class on top of this service which locally binds to it. Now when I export the service as a jar and link to it from another application (this application instantiate the wrapper class). When I run the application, I am getting the ClassCastException: android.os.BinderProxy cannot be cast to xxx$LocalBinder caused by the local bind in the wrapper class:

service = ((LocalBinder) binder).getService();

The binder here is of type BinderProxy instead of localbinder and hence the crash.

The only way that this application works is when the package name of the app is the same as the service package name (I assume Android thinks that the service is local).

private final IBinder localBinder = new LocalBinder();
    public class LocalBinder extends Binder {
    xxxService getService() {
        return xxxService.this;
    }
}
    

and

public IBinder onBind( Intent intent ) {
    IBinder result = null;
    result = localbinder;
    return result;
}

Then in my wrapper class onServiceConnected:

    public void onServiceConnected( ComponentName name, IBinder binder) {   

         xxxService = ((LocalBinder) binder).getService();

Finally my wrapper class constructor:

public xxxServiceManager( Context context ) throws Exception {
    this.context = context;
    xxxServiceManagerIntent = new Intent( "providerAPI" );
    xxxServiceManagerIntent.setClassName( "com.yyy", "com.yyy.xxxService" );

    context.startService( xxxServiceManagerIntent );


    context.bindService( xxxServiceManagerIntent, serviceConnection, Context.BIND_AUTO_CREATE );

Then in the main application that uses this jar, if you set the package name

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yyy.provider" //the same as the service (which does not make sense)

everything work, but obviously I want to set another package name. Is there any way how to redesign or make this work?

thanks!


Solution

  • see this

    If your service is used only by the local application and does not need to work across processes, then you can implement your own Binder class that provides your client direct access to public methods in the service.

    Note: This works only if the client and service are in the same application and process, which is most common. For example, this would work well for a music application that needs to bind an activity to its own service that's playing music in the background.