Android ClassCast исключение при привязке к сервису - PullRequest
6 голосов
/ 07 ноября 2011

Хорошо, я новичок в разработке для Android и пытаюсь привязать сервис, чтобы я мог вызывать методы сервиса после его запуска.Активность и Сервис, описанные ниже, являются частью одного и того же приложения, поэтому там не должно быть никаких проблем, но каждый раз, когда я запускаю свое приложение, я получаю следующую ошибку:

java.lang.ClassCastException: android.os.BinderProxy

Строка, в которой это происходит:

LocalBinder binder = (LocalBinder) service;

Код моей активности (упрощенно):

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

}

Служба:

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...

    }

}

И, наконец, мой 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();
    }
}

Я понимаю значение исключения ClassCast, но не могу понять, что делать!Я следовал примеру в документации Google, но он все еще не работает.Кто-нибудь может пролить свет на то, что может быть причиной этого?

Заранее спасибо!

Ответы [ 4 ]

32 голосов
/ 09 июня 2012

Удалить атрибут process в вашем AndroidManifest.xml вашего сервиса.

4 голосов
/ 21 сентября 2012

Была та же ошибка. Я добавил атрибут android: process = ": process_description" в манифест. Когда вы добавляете его, ваш сервис создается как отдельный процесс, и, следовательно, вы получаете экземпляр binderProxy (отсюда исключение приведения класса)

3 голосов
/ 14 марта 2012

Если вы пытаетесь привязать к локальной службе, чем да, вы можете просто разыграть ее. Однако, если вы пытаетесь привязать к удаленному (отдельному процессу) сервису, вы должны использовать метод AIDL, как предписано в этой статье.

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

3 голосов
/ 07 ноября 2011

LocalBinder, переданный в onServiceConnected, имеет аргумент общего типа, в то время как ваша локальная переменная LocalBinder binder не имеет его.

Устраните это тем или иным способом, либо удалив универсальный тип из определения LocalBinder, либо добавив его к объявлению связывателя локальной переменной в 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();
    }
}

Нет реальногонужно возиться со слабыми ссылками и еще много чего.просто обязательно отмените привязку (в примере я этого не сделал)

Если вы хотите вызывать методы обслуживания как можно скорее, просто поместите вызовы в onServiceConnected после того, как вы установите mBinder.в противном случае просто вызовите из других обратных вызовов (события onClick и еще много чего).

...