Связанные службы Android: почему мы приводим этот экземпляр IBinder к экземпляру IBinder?

В документах для разработчиков для связанных служб приведен следующий пример кода для «Расширение класса Binder» в разделе «Создание связанной службы». Приведен следующий фрагмент кода (я удалил ненужные биты), в котором Service возвращает IBinder из своего onBind()метода:

public class LocalService extends Service {
    // Binder given to clients
    private final IBinder mBinder = new LocalBinder();
    ...
    /**
     * Class used for the client Binder.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */
    public class LocalBinder extends Binder {
        LocalService getService() {
            // Return this instance of LocalService so clients can call public methods
            return LocalService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder; //**********************************************************
    }
    ...
}

Затем в нашем клиенте мы получаем объект mBinder (который является экземпляром LocalBinder) в методе onServiceConnected() объекта ServiceConnection. Мой вопрос: почему мы пытаемся преобразовать экземпляр LocalBinder, переданный как argument в onServiceConnected(), в экземпляр LocalBinder в операторе LocalBinder binder = (LocalBinder) service;?

public class BindingActivity extends Activity {
    LocalService mService;
    boolean mBound = false;
    ...

    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
                IBinder service) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mBound = false;
        }
    };
    ...
}

person Solace    schedule 21.10.2014    source источник


Ответы (2)


Определение ServiceConnection.onServiceConnected() — это

public void onServiceConnected (имя_компонента className, служба IBinder)

Обратите внимание, что параметр IBinder - ServiceConnection не знает, какую службу или какую IBinder реализацию возвращает служба - это знаете только вы, поэтому вам нужно привести ее к правильному типу.

person ianhanniballake    schedule 21.10.2014

Поскольку единственная информация о типе, которую вы имеете в onServiceConnected, заключается в том, что вы получаете объект типа IBinder. IBinder не имеют метода getService, поэтому необходимо выполнить приведение объекта IBinder к объекту типа LocalBinder. Затем вы можете вызвать метод getService. Вот как работает статическая типизация.

person dcow    schedule 21.10.2014
comment
Язык является статически типизированным, если тип переменной известен во время компиляции. На практике это означает, что вы, как программист, должны указать тип каждой переменной. Ссылка. Теперь я не мог выяснить, как это связано со статической типизацией. - person Solace; 22.10.2014
comment
@Зара, потому что кастинг. Вы не используете динамические языки (просто терпите неудачу). Когда вы выполняете кастинг, вы говорите, что хотите переопределить информацию о типе, доступную во время компиляции, потому что вы лучше знаете. Вы ведете себя динамично. - person dcow; 22.10.2014