问题
I have a Service
that I am trying to bind to my main Activity
, but I am receiving a
java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.walintukai.rubix.ConnectionService$LocalBinder.
I have declared the service in my manifest. Why is this happening?
Manifest Declaration
<service android:name=".ConnectionService" />
Service (simplified code)
public class ConnectionService extends Service {
static final String TAG = ConnectionService.class.getName();
private BluetoothAdapter mBtAdapter = null;
public BluetoothGatt mBluetoothGatt = null;
private ConnectionServiceEventListener mIRedBearServiceEventListener;
HashMap<String, BluetoothDevice> mDevices = null;
private BluetoothGattCharacteristic txCharc = null;
private final IBinder mBinder = new LocalBinder();
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class LocalBinder extends Binder {
public ConnectionService getService() {
return ConnectionService.this;
}
}
@Override
public void onCreate() {
super.onCreate();
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBtAdapter = bluetoothManager.getAdapter();
if (mBtAdapter == null)
return;
if (mDevices == null)
mDevices = new HashMap<String, BluetoothDevice>();
}
@Override
public void onDestroy() {
if (mBluetoothGatt == null)
return;
mBluetoothGatt.close();
mBluetoothGatt = null;
super.onDestroy();
}
}
Main Activity
public class MainActivity extends ActionBarActivity {
private ConnectionService service;
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i("ConnectionService", "Disconnected");
service = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
LocalBinder binder = (LocalBinder) service;
service = (IBinder) binder.getService();
if (service != null) {
Log.i("RedBearService", "Connected");
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().add(R.id.container, ViewPagerFragment.newInstance()).commit();
}
}
@Override
public void onStart() {
super.onStart();
startService();
}
@Override
public void onStop() {
super.onStop();
stopService();
}
private void startService() {
Intent service = new Intent(this, ConnectionService.class);
bindService(service, connection, Context.BIND_AUTO_CREATE);
}
private void stopService() {
unbindService(connection);
}
}
Stacktrace
07-30 17:19:39.065: E/AndroidRuntime(20891): java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.walintukai.rubix.ConnectionService$LocalBinder
07-30 17:19:39.065: E/AndroidRuntime(20891): at com.walintukai.rubix.MainActivity$1.onServiceConnected(MainActivity.java:58)
07-30 17:19:39.065: E/AndroidRuntime(20891): at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1110)
07-30 17:19:39.065: E/AndroidRuntime(20891): at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1127)
07-30 17:19:39.065: E/AndroidRuntime(20891): at android.os.Handler.handleCallback(Handler.java:733)
07-30 17:19:39.065: E/AndroidRuntime(20891): at android.os.Handler.dispatchMessage(Handler.java:95)
07-30 17:19:39.065: E/AndroidRuntime(20891): at android.os.Looper.loop(Looper.java:136)
07-30 17:19:39.065: E/AndroidRuntime(20891): at android.app.ActivityThread.main(ActivityThread.java:5050)
07-30 17:19:39.065: E/AndroidRuntime(20891): at java.lang.reflect.Method.invokeNative(Native Method)
07-30 17:19:39.065: E/AndroidRuntime(20891): at java.lang.reflect.Method.invoke(Method.java:515)
07-30 17:19:39.065: E/AndroidRuntime(20891): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
07-30 17:19:39.065: E/AndroidRuntime(20891): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
07-30 17:19:39.065: E/AndroidRuntime(20891): at dalvik.system.NativeStart.main(Native Method)
回答1:
You've got it flipped:
public void onServiceConnected(ComponentName name, IBinder service) {
LocalBinder binder = (LocalBinder) service;
service = (IBinder) binder.getService();
...
}
should be:
public void onServiceConnected(ComponentName name, IBinder service) {
LocalBinder binder = (LocalBinder) service;
MainActivity.this.service = (ConnectionService) binder.getService();
...
}
回答2:
This question is a few years old and the accepted answer didn't work for me. Perhaps something has changed in the Android environment since the question was asked and answered.
But I stumbled on a simple solution that worked. I saw another question on SO that was trying to start 2 services and they had a similar error (Getting java.lang.ClassCastException: android.os.BinderProxy every time i declare and run two services). One of the answers (@Coeffect) mentioned that the 2 services don't necessarily run in the same process.
I got to thinking that it is possible (probable?) that in my case the activity and the service were run in different processes. So I added the android:process
element to both my activity and my server, and that fixed it.
Here's an example AndroidManifest.xml. Note that both the <activity>
and <service>
tags include android:process=":location"
:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.byteslinger.locationservice">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:process=":location"
android:allowBackup="true"
android:icon="@mipmap/icon"
android:label="@string/app_name"
android:roundIcon="@mipmap/icon"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"
android:process=":location"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:process=":location"
android:name=".LocationService"
android:enabled="true" />
</application>
</manifest>
回答3:
I also encountered this problem. My situation is like this.
My activity and service are not in a same process.
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyService"
android:process=":remoute"/>
I want to bind the service with activity. Then I ran into the same problem. I solved it with this method.
@Override
public IBinder onBind(Intent arg0) {
int numb = arg0.getIntExtra("numb", 0);
Log.e("WillWolf", "numb-->" + numb);
if(numb == 1) {
Log.e("WillWolf", "local binder");
return new LocalBinder();
} else {
Log.e("WillWolf", "remote binder");
return remoteBinder;
}
}
Please pay attention to this. When you call the bindService() method multiple times, onBind() is only called back once by default.If you want onBind() to execute multiple times, you should do this.
Intent intent = new Intent(context, MyService.class);
intent.setType("remote");// should be different
context.bindService(intent, coon, Context.BIND_AUTO_CREATE);
I hope it can help you.
来源:https://stackoverflow.com/questions/25049176/java-lang-classcastexception-android-os-binderproxy-cannot-be-cast-to-localbind