从另一个 Activity 绑定到本地服务时出现 ClassCastException

发布于 2024-10-09 01:40:27 字数 816 浏览 6 评论 0原文

在我的应用程序中,我有两个独立的 APK。第一个 APK 中的 Activity (A1) 启动本地服务并能够调用该服务提供的方法。随后,活动 A1 从第二个 APK 启动另一个活动 (A2)。 A2 活动尝试连接到 A1 启动的本地服务。两个活动都在具有相同 SharedUserID 的同一进程中运行。提供的服务接口如LocalService的API示例所示。服务的 onBind 方法返回 LocalBinder 实例,该实例具有 getService() 方法。 当调用 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)
  {

  }


 }

In my application I have two separated APKs. The Activity (A1) from the first APK starts local service and is able to call methods provided by this Service. Later the activity A1 starts another activity (A2) from the second APK. The A2 activity tries to connect to the local service started by A1. Both activities are running in the same process with the same SharedUserID. Service interface is provided as shown in API examples of LocalService. onBind method of service returns LocalBinder instance which has method getService().
When onServiceConnected of A2 is called I got ClassCastException when I try to cast from IBinder to MyService.LocalBinder.

In the debugger I can see that the service argument of onServiceConnected of A2 activity is the right instance of MyService.LocalBinder. I can even watch all attributes of MyService in debugger, but when I tries to cast the IBinder service to the MyService.LocalBinder I got the ClassCastException exception? Is there some way around or do I have to use AIDL?

public void onServiceConnected(ComponentName className, IBinder service)
{

  try
  {
       MyService.LocalBinder binder = (MyService.LocalBinder)service;
       m_IService = binder.getService();
  }
  catch(ClassCastException e)
  {

  }


 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

太阳哥哥 2024-10-16 01:40:27

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


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

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

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

Not sure about this, but I'm guessing that you have compiled MyService.LocalBinder into both A1 and A2 apks. That would produce this kind of exception, because while they have the same name and the same code, they're still two separate class files. I think you would need to move the class into a shared library to make this work.


Update (responding to comment): I don't see how using an interface would be any different; as with the class, the interface would be instantiated differently on the client and server, and so result in a cast exception. You might be able to use reflection to work around this, but I don't recommend that approach -- it may not be supported by either AndroidOS or the DalvikVM.

I think the best course is to try creating the AIDL interface and see if it does the job. It could be 10x easier than trying to do something that Android seems deliberately designed to prevent.

But if you want to keep pursuing your current approach, one possible path would be to use the ClassLoader to load the client class into the server. I'm not sure if this can be made to work either.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文