java.lang.ClassCastException: android.os.BinderProxy нельзя преобразовать в LocalBinder

У меня есть Service, который я пытаюсь привязать к своему основному Activity, но получаю

java.lang.ClassCastException: android.os.BinderProxy нельзя преобразовать в com.walintukai.rubix.ConnectionService$LocalBinder.

Я объявил службу в своем манифесте. Почему это происходит?

Декларация манифеста

<service android:name=".ConnectionService" />

Сервис (упрощенный код)

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();
}

}

Основное действие

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);
}

}

Трассировка стека

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)

person The Nomad    schedule 31.07.2014    source источник
comment
Вы запускаете службу в том же процессе, что и приложение?   -  person Onik    schedule 31.07.2014
comment
@Оник Должно быть. Как я могу проверить? Я запускаю и привязываю службу к вызову onStart моей основной деятельности.   -  person The Nomad    schedule 31.07.2014
comment
Пожалуйста, покажите, как вы объявляете службу в файле манифеста.   -  person Onik    schedule 31.07.2014
comment
Можете ли вы также указать свой основной код деятельности?   -  person Oleg Gryb    schedule 31.07.2014
comment
Отредактировано, чтобы включить основное действие и объявление манифеста.   -  person The Nomad    schedule 31.07.2014
comment
Сейчас я получаю другую ошибку: java.lang.ClassCastException: com.walintukai.rubix.ConnectionService не может быть приведен к android.os.IBinder, который находится в этой строке: service = (IBinder) binder.getService();   -  person The Nomad    schedule 31.07.2014
comment
Вы уверены, что ваш упрощенный код верен? OnServiceConnected действия неправильно возвращает результат из метода getService обратно в IBinder.   -  person Larry Schiefer    schedule 31.07.2014
comment
ВАУ... ладно, я чувствую себя очень глупо. Я назвал переменную ConnectionService service, и это мешало работе метода, потому что у него была переменная service, как в параметрах... Спасибо за помощь, ребята! /хлопок по лбу   -  person The Nomad    schedule 31.07.2014


Ответы (3)


Вы перепутали:

public void onServiceConnected(ComponentName name, IBinder service) {
    LocalBinder binder = (LocalBinder) service;
    service = (IBinder) binder.getService();
    ...
}

должно быть:

public void onServiceConnected(ComponentName name, IBinder service) {
    LocalBinder binder = (LocalBinder) service;
    MainActivity.this.service = (ConnectionService) binder.getService();
    ...
}
person dcow    schedule 31.07.2014
comment
Я только что понял это, но так как вы написали в то же время, я дам вам баллы. - person The Nomad; 31.07.2014

Этому вопросу несколько лет, и принятый ответ мне не помог. Возможно, что-то изменилось в среде Android с тех пор, как вопрос был задан и на него был дан ответ.

Но я наткнулся на простое решение, которое сработало. Я видел еще один вопрос на SO, который пытался запустить 2 службы, и у них была аналогичная ошибка (Получение java.lang.ClassCastException: android.os.BinderProxy каждый раз, когда я объявляю и запускаю две службы). В одном из ответов (@Coeffect) упоминалось, что две службы не обязательно работают в одном и том же процессе.

Я подумал, что возможно (вероятно?), что в моем случае активность и служба запускались в разных процессах. Поэтому я добавил элемент android:process как в свою активность, так и в свой сервер, и это исправило его.

Вот пример AndroidManifest.xml. Обратите внимание, что оба тега <activity> и <service> включают 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>
person ByteSlinger    schedule 04.02.2018
comment
Интересный. Потому что, когда вы устанавливаете процесс для приложения, он автоматически устанавливает процесс для остальных компонентов (действия, службы, получателя...). И установка процесса в приложении обычно ничем не отличается от его отсутствия вообще, поскольку все компоненты уже работают в одном и том же процессе, если вы опускаете тег процесса. - person frankish; 03.09.2019
comment
Зачем добавлять android:process в действие? - person IgorGanapolsky; 13.04.2020

Я также столкнулся с этой проблемой. Моя ситуация такова.

Моя деятельность и служение не находятся в одном и том же процессе.

<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"/>

Я хочу связать службу с активностью. Затем я столкнулся с той же проблемой. Я решил это с помощью этого метода.

@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;
    }
}

Пожалуйста, обратите на это внимание. Когда вы вызываете метод bindService() несколько раз, onBind() по умолчанию вызывается только один раз. Если вы хотите, чтобы onBind() выполнялся несколько раз, вы должны сделать это.

Intent intent = new Intent(context, MyService.class);
    intent.setType("remote");// should be different
    context.bindService(intent, coon, Context.BIND_AUTO_CREATE);

Я надеюсь, что это может помочь вам.

person WillWolf    schedule 17.07.2019
comment
что такое remoteBinder здесь? - person Lior Iluz; 19.05.2020