【问题标题】:ClassCastException when binding to local service from another Activity从另一个 Activity 绑定到本地服务时出现 ClassCastException
【发布时间】:2010-12-24 14:59:37
【问题描述】:

在我的应用程序中,我有两个独立的 APK。第一个 APK 的 Activity (A1) 启动本地服务,并能够调用该服务提供的方法。稍后活动 A1 从第二个 APK 启动另一个活动 (A2)。 A2 活动尝试连接到由 A1 启动的本地服务。这两个活动都在具有相同 SharedUserID 的同一进程中运行。提供服务接口,如 LocalService 的 API 示例所示。服务的 onBind 方法返回具有方法 getService() 的 LocalBinder 实例。 当调用 A2 的 onServiceConnected 时,当我尝试从 IBinder 转换为 MyService.LocalBinder 时出现 ClassCastException。

在调试器中,我可以看到 A2 活动的 onServiceConnected 的服务参数是 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)
  {

  }


 }

【问题讨论】:

    标签: android service local classcastexception


    【解决方案1】:

    对此不确定,但我猜您已将 MyService.LocalBinder 编译到 A1 和 A2 apk 中。这会产生这种异常,因为虽然它们具有相同的名称和相同的代码,但它们仍然是两个独立的类文件。我认为您需要将该类移动到共享库中才能完成这项工作。


    更新(回应评论):我看不出使用界面会有什么不同;与类一样,接口将在客户端和服务器上以不同方式实例化,因此会导致强制转换异常。您也许可以使用reflection 来解决这个问题,但我不推荐这种方法——AndroidOS 或 DalvikVM 可能都不支持它。

    我认为最好的方法是尝试创建 AIDL 接口,看看它是否能完成这项工作。这可能比尝试做一些 Android 似乎有意阻止的事情要容易 10 倍。

    但如果您想继续采用当前的方法,一个可能的路径是使用ClassLoader 将客户端类加载到服务器中。我不确定这是否也可以工作。

    【讨论】:

    • 我在 Library Project 中有 MyService 类,所以它在两个 APK 中都被编译,这是什么意思?或者有没有其他方法可以跨更多应用共享 MyService?
    • @esmeralda2:如果您确定serviceMyService.LocalBinder 的一个实例,那么当该转换引发异常时,我不知道除了重复之外的其他可能原因MyService.LocalBinder 的定义。您确定它没有在多个位置或多个 jar 文件中定义吗?作为测试,尝试在演员表之前实例化一个假 LocalBinder:MyService.LocalBinder fake = new MyService.LocalBinder();,然后查看它们是否具有相同的类:if (fake.getClass() != service.getClass() {/* report an error */}
    • 嗨,丹,你是对的,这就是问题所在。当我将 MyService 实现放入库项目时,如果 APK1 和 APK2 使用此库。项目然后 MyService 实现在两个 APK 中。然后确实是 service.getClass() != MyService.LocalBinder.getClass()。有什么办法吗?我不是 java 专家,我宁愿在 C 中工作,所以有什么东西可以作为共享库吗?在 java 中,这是 JAR 文件吗?如果我为 android 开发,是否可以将 MyService 移动到 JAR 文件?或者我可以将 MyService 移动到 APK1 并在 APK2 中将服务转换到将在 Library 项目中的某个接口?
    • @esmeralda2:图书馆项目好像是专门用来分享源代码的;对象从库中复制到 apk 中。 (直到现在我还没有完全意识到这一点。)我以为我已经看到了一种在 apk 文件之间共享组件的方法,而无需复制它们,但我现在找不到它。此时使用 AIDL 可能是最简单的。
    • 我想避免 AIDL。首先,我必须为我想要传递给/从服务的 PDU 实施 Parcel,其次我害怕性能损失。如果您找到如何在 APK 之间共享对象的方法,请告诉我。您如何看待我将服务参数转换为接口的方法,该接口将提供 getService 方法而不是使用 getService() 方法将其转换为 LocalBinder 类?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    相关资源
    最近更新 更多