从已绑定的服务返回不同的 Binder

Posted

技术标签:

【中文标题】从已绑定的服务返回不同的 Binder【英文标题】:Return a different Binder from already bound service 【发布时间】:2019-04-11 08:07:38 【问题描述】:

我有一个服务,它已经通过AIDL 被外部应用程序绑定。

但是,有些服务请求需要启动Activity。 由于我无法从服务中调用startActivityForResult,因此我决定也将我的本地活动绑定到该服务。

(伪代码)如下所示:

class MyService extends Service
    public IBinder onBind(Intent intent)
        if (intent.hasExtra("LocalBindingRequest"))
            return getLocalBinder();
        else 
           return getAidlBinder();
        
    


class ExternalApp extends Activity
    void someFunc()
        Intent i = new Intent(new ComponentName("com.my.pkg", "com.my.pkg.MyService");
        bindService(i, myServiceConnection, Context.BIND_AUTO_CREATE);
    


class InternalApp extends Activity
    MyService mService;

    void someFunc()
        Intent i = new Intent(new ComponentName("com.my.pkg", "com.my.pkg.MyService")
           .putExtra("LocalBindingRequest", true);
        bindService(i, myServiceConnection, Context.BIND_AUTO_CREATE);
    

    public void onServiceConnected(ComponentName cn, IBinder service)
        InternalBinder ib = (LocalBinder)service;
        mService = ib.getService();

    


流程是这样的:

ExternalApp 绑定到 AidlBinder ExternalApp 调用需要 Service 来启动 Activity 的函数 服务启动 Activity 内部 Activity 尝试绑定 我得到一个异常(显然没有在onBindonServiceConnected 中遇到断点)

java.lan.ClassCastException: AidlService 无法转换为 InternalBinder


服务不能返回不同的 Binder 吗?

如果没有,我该怎么做才能将 Result 传播回已经绑定的 MyService?

【问题讨论】:

【参考方案1】:

好的,我应该阅读onBind(Intent)中的文档

Intent:用于绑定到此服务的 Intent,如给定 Context.bindService。请注意,包含在 此处不会显示此时的意图。

这就是为什么我得到了急救服务。解决方法是:

class InternalApp extends Activity
    MyService mService;

    void someFunc()
        Intent i = new Intent(new ComponentName("com.my.pkg", "com.my.pkg.MyService");
        i.setAction("LocalBindingRequest");
        bindService(i, myServiceConnection, Context.BIND_AUTO_CREATE);
    

    public void onServiceConnected(ComponentName cn, IBinder service)
        InternalBinder ib = (LocalBinder)service;
        mService = ib.getService();

    



class MyService extends Service
    public IBinder onBind(Intent intent)
        if ("LocalBindingRequest".equals(intent.getAction())
            return getLocalBinder();
        else 
           return getAidlBinder();
        
    

我们可以为每个绑定请求使用单独的绑定器

【讨论】:

以上是关于从已绑定的服务返回不同的 Binder的主要内容,如果未能解决你的问题,请参考以下文章

Android Binder跨进程与非跨进程的传输异同源码分析

Android面试题总结(一天搞一个吧)

Android面试题总结(一天搞一个吧)

Android Binder解析

Binder 机制AIDL 分析 ( 创建 Service 服务 | 绑定 Service 远程服务 )

IPC机制之Binder连接池