В моем приложении у меня есть два разделенных APK. Действие (A1) из первого APK запускает локальную службу и может вызывать методы, предоставляемые этой службой. Позже активность A1 запускает другое действие (A2) со второго APK. Активность A2 пытается подключиться к локальной службе, запущенной A1. Оба действия работают в одном и том же процессе с одним и тем же SharedUserID. Сервисный интерфейс предоставляется, как показано в примерах API LocalService. Метод onBind службы возвращает экземпляр LocalBinder, у которого есть метод getService(). Когда onServiceConnected из A2 вызывается, я получил ClassCastException, когда я пытаюсь использовать из IBinder в MyService.LocalBinder.
В отладчике я вижу, что аргумент службы onServiceConnected из A2-активности является правильным экземпляром MyService.LocalBinder. Я даже могу отслеживать все атрибуты MyService в отладчике, но когда я пытаюсь передать службу IBinder в MyService.LocalBinder, я получил исключение ClassCastException? Есть ли какой-то путь или мне нужно использовать AIDL?
public void onServiceConnected(ComponentName className, IBinder service)
{
try
{
MyService.LocalBinder binder = (MyService.LocalBinder)service;
m_IService = binder.getService();
}
catch(ClassCastException e)
{
}
}
Не уверен в этом, но я предполагаю, что вы собрали MyService.LocalBinder в аплеты A1 и A2. Это вызвало бы такое исключение, потому что, хотя у них одно и то же имя и тот же код, они все еще являются двумя отдельными файлами классов. Я думаю, вам нужно будет переместить класс в общую библиотеку, чтобы сделать эту работу.
Обновить (ответ на комментарий): я не вижу, как использование интерфейса будет другим; как и в случае с классом, интерфейс будет создаваться по-разному на клиенте и сервере и, таким образом, приведет к исключению литья. Вы могли бы использовать отражение, чтобы обойти это, но я не рекомендую этот подход - он может не поддерживаться ни AndroidOS, ни DalvikVM.
Я думаю, что лучший способ - попробовать создать интерфейс AIDL и посмотреть, выполняет ли он эту работу. Это может быть проще в 10 раз, чем пытаться сделать что-то, что Android намеренно предназначено для предотвращения.
Но если вы хотите продолжить свой текущий подход, одним возможным будет использование ClassLoader для загрузки класса клиента на сервер. Я не уверен, что это может быть сделано для работы.
service
является экземпляромMyService.LocalBinder
когда при этом приведенииMyService.LocalBinder
исключение, то я не знаю другой возможной причины, кроме дублированного определенияMyService.LocalBinder
. Вы уверены, что он не определен более чем в одном месте или в нескольких jar-файлах? В качестве теста попробуйте создать поддельный LocalBinder непосредственно перед приведением:MyService.LocalBinder fake = new MyService.LocalBinder();
а затем посмотреть, имеют ли они один и тот же класс:if (fake.getClass() != service.getClass() {/* report an error */}