Reputation: 3687
I am trying to bind to a custom service with no success.
My custom service
public class CustomService extends Service {
private CustomReceiver mReceiver;
private final CustomBinder mBinder = new CustomBinder();
public class CustomBinder extends Binder implements ICustomService {
// Implementation of the interface
}
public interface ICustomService {
// Public interface to comunicate to the service
}
@Override
public IBinder onBind(Intent intent) {
Log.d("customservice", "Service bound.");
mReceiver = intent.getParcelableExtra("receiver"); // ERROR HERE!
return mBinder;
}
// Other methods
My custom receiver
public class CustomReceiver extends ResultReceiver {
public interface IReceiver {
public void onReceiveResult(int resultCode, Bundle resultData);
}
private IReceiver mReceiver;
public CustomReceiver(Handler handler) {
super(handler);
}
public void setReceiver(IReceiver receiver) {
mReceiver = receiver;
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
if (mReceiver != null) {
mReceiver.onReceiveResult(resultCode, resultData);
}
}
}
My activity
public class MainActivity extends Activity implements CustomReceiver.IReceiver {
IRegressiveService mService;
CustomReceiver mReceiver;
boolean mBound = false;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
mService = (ICustomService) service;
mBound = true;
}
public void onServiceDisconnected(ComponentName name) {
mBound = false;
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
//...
mReceiver = new CustomReceiver(new Handler());
mReceiver.setReceiver(this);
Intent bindServiceIntent = new Intent(this, CustomService.class);
bindServiceIntent.putExtra("receiver", mReceiver);
bindService(bindServiceIntent, mConnection, Context.BIND_AUTO_CREATE);
}
public void onReceiveResult(int resultCode, Bundle resultData) {
//...
}
//...
}
Stacktrace (incomplete)
04-29 20:23:55.851: E/AndroidRuntime(690): FATAL EXCEPTION: main
04-29 20:23:55.851: E/AndroidRuntime(690): java.lang.RuntimeException: Unable to bind to service [package].CustomService@44f38cd8 with Intent { cmp=[package].CustomService (has extras) }: java.lang.ClassCastException: android.os.ResultReceiver
04-29 20:23:55.851: E/AndroidRuntime(690): at android.app.ActivityThread.handleBindService(ActivityThread.java:2996)
[...]
04-29 20:23:55.851: E/AndroidRuntime(690): Caused by: java.lang.ClassCastException: android.os.ResultReceiver
04-29 20:23:55.851: E/AndroidRuntime(690): at [package].CustomService.onBind(CustomService.java:37)
04-29 20:23:55.851: E/AndroidRuntime(690): at android.app.ActivityThread.handleBindService(ActivityThread.java:2983)
[...]
In short
In the Activity, I pass to the Service a instance of CustomReceiver
(a ResultReceiver
subclass) with the "receiver" key. But when I try to recover this object, in the Service, ClassCastException
is raised. Why? How can I fix this?
I am targeting API level 8.
And I can not find this behavior in any of other SO questions.
Upvotes: 3
Views: 4636
Reputation: 11
I was having the exact same issue with the ClassCastException
and it did not make any sense to me. I saw the answer here about setting the mReceiver
to just use a ResultReceiver
instead of the CustomReceiver
in the Service. I did that and still got the same error, but I noticed that my import
Statements were not the same.
In my MainActivity I imported the statement:
import android.support.v4.os.ResultReceiver;
However in my service I had imported the statement:
import android.os.ResultReceiver;
I made sure in my service and my MainActivity I used following:
import android.support.v4.os.ResultReceiver;
It now works properly! Hope this helps someone!
I'm also a few years late..
Upvotes: 1
Reputation: 48871
I've just checked my code. Try declaring mReceiver
in your Service
as a base ResultReceiver
as follows...
public class CustomService extends Service {
private ResultReceiver mReceiver;
...
}
This is what I do and I don't get a ClassCastException
in my Service
when getting the receiver from the Intent
(mine is also a custom ResultReceiver
).
Upvotes: 2
Reputation: 64700
A BroadcastReceiver
is (by default) not Parcelable
. So you'll expect to get a ClassCastException. If you need to pass a specific instance add a setter method to your Service and then call that method from your ServiceConnection implementation with the object.
Upvotes: -1