stven_king
静默加载
采纳率0%
2017-06-30 03:28 阅读 3.3k

activity绑定Service成功时ServiceConnection的回调问题?

5

Activity绑定Service时ServiceConnection回调onServiceConnected传过来的IBinder对象,为什么相同进程下是Binder对象,不同进程下是BinderProxy对象。

 private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "IBinder.class.Name : " + service.getClass().getName());
            mService = new Messenger(service);
            Message msg = Message.obtain();
            Bundle data = new Bundle();
            String msgString = "hello ,this is client.";
            data.putString("msg", msgString);
            msg.setData(data);
            msg.replyTo = clientHandler;
            try {
                mService.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

3条回答 默认 最新

  • baidu_26611019 蚂蚁冲锋队 2017-06-30 05:45

    首先android的进程间通信采用的是IPC机制,IPC的主角就是Binder,整个通信机制在设计上是采用了代理模式来实现。
    比如:A(客户端)进程要调用B(服务)进程的一个方法funcB(),
    这个时候A并不能直接去访问B中的方法(出于数据保护,进程间是不允许直接通信的,IPC利用了共享内存来实现通信的)。
    IPC的大致思路是:
    A将这个请求委托给客户端的Binder代理,
    进而将请求转给BinderDriver,
    再将请求给服务端的Binder代理,
    最后通过Binder代理调用B中的funcB()。

    如果不去考虑中间的过程,客户端调用远程服务(跨进程)的时候,都是获得一个远程服务在本地的代理BinderProxy对象。
    通过该对象实现RPC的调用。

    点赞 1 评论 复制链接分享
  • baidu_26611019 蚂蚁冲锋队 2017-06-30 07:02

    Android技术内幕.系统卷.pdf
    ANDROID框架揭秘.pdf
    这两篇有对源码做详细的说明

    点赞 评论 复制链接分享
  • u011315960 珠穆朗玛小王子 2017-06-30 08:39

    之前我也仔细的去看过AIDl的使用,了解了绑定服务的过程,被你这么一问我又重新看到了一遍...

    首先我要说我现在还没办法给你完整的分析整个的流程,因为我不懂c,而且我也没有完整的Android系统源码,但是我可以帮你分析一下:

    首先Android系统多个层级,除了你想要知道的FrameWork框架层,还有驱动层,驱动层是由c实现的,
    例如进程的创建,各种服务的启动(例如控制音量或者是亮度,最终调用的是都是c)。
    所以跨进行通信(AIDl),必然会调用驱动层的东西。
    (创建进程的开销很大,例如把WebActivity设置到新进程中,第一次会很慢)

    你可以先看这个篇博客,他分析了bindService整个流程:
    http://blog.csdn.net/zhangyongfeiyong/article/details/51953300

    但是注意里面有些方法抛出了TransactionTooLargeException异常,这个异常会在跨进程通信的对象内存过大抛出(例如我们的方法参数和返回值),
    也就是说这个地方有可能在什么条件下,会去调用c的代码,我猜测很有可能是在这个过程中,把Binder转化成了BinderProxy。

    接下来再看这个,看看里面整理的c的代码,虽然可能是看不懂,但是你会看到Binder和BinderProxy,里面有判断具体要使用哪一个。
    http://xxw8393.blog.163.com/blog/static/372568342009828101455182/

    所以你想要知道他俩具体转换的地方,我猜测是在c代码的部分,我也只能帮你到这里了,如果你有了新的发现,一定要告诉我。

    点赞 评论 复制链接分享

相关推荐