Android Binder进程间通信---注册Service组件---启动Binder线程池

本文参考《Android系统源代码情景分析》,作者罗升阳

一、测试代码:

~/Android/external/binder/server

----FregServer.cpp

~/Android/external/binder/common

----IFregService.cpp

----IFregService.h

~/Android/external/binder/client

----FregClient.cpp

Binder库(libbinder)代码:

~/Android/frameworks/base/libs/binder

----BpBinder.cpp

----Parcel.cpp

----ProcessState.cpp

----Binder.cpp

----IInterface.cpp

----IPCThreadState.cpp

----IServiceManager.cpp

----Static.cpp

~/Android/frameworks/base/include/binder

----Binder.h

----BpBinder.h

----IInterface.h

----IPCThreadState.h

----IServiceManager.h

----IBinder.h

----Parcel.h

----ProcessState.h

驱动层代码:

~/Android//kernel/goldfish/drivers/staging/android

----binder.c

----binder.h

二、源码分析

继续上一篇Android Binder进程间通信---注册Service组件---发送和处理BC_REPLY返回协议http://blog.csdn.net/jltxgcy/article/details/26339313,执行完waitForResponse函数,参考Android Binder进程间通信---注册Service组件---Client发送BC_TRANSACTION。应该返回IPCThreadState类的transact方法,再返回BpBinder类的transact函数,最后返回BpServiceManager类addService函数。最后再返回FregService类的main函数,实现如下:

~/Android/external/binder/server

----FregServer.cpp

int main(int argc, char** argv)
{
	FregService::instantiate();

	ProcessState::self()->startThreadPool();//启动一个Binder线程池
	IPCThreadState::self()->joinThreadPool();//主线程加入线程池

	return 0;
}

首先当前进程的ProcessState对象的成员函数startThreadPool来启动一个Binder线程池,接着继续调用当前线程的IPCThreadState对象的成员函数joinThreadPool,将当前线程加入到前面所启动的Binder线程池中去等待和处理来自Client进程的进程间通信请求。

下面我们就分析ProcessState类的成员函数startThreadPool的实现,在分析过程中,同时也会分析IPCThreadState类的成员函数joinThreadPool的实现。

ProcessState类的成员函数startThreadPool的实现如下:

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

void ProcessState::startThreadPool()
{
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) {//默认值为false
        mThreadPoolStarted = true;//防止它的成员函数spawnPooledThread被重复调用来启动Binder线程池
        spawnPooledThread(true);
    }
}

当前进程的ProcessState对象的成员变量mThreadPoolStarted被初始化为false,当它将一个Binder线程池启动起来之后,就会将内部的成员变量mThreadPoolStarted的值设置为true,防止它的成员函数spawnPooledThread被重复调用来启动Binder线程池。spawnPooledThread函数实现如下:

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
        int32_t s = android_atomic_add(1, &mThreadPoolSeq);
        char buf[32];
        sprintf(buf, "Binder Thread #%d", s);
        LOGV("Spawning new pooled thread, name=%s\n", buf);
        sp<Thread> t = new PoolThread(isMain);//isMain为true
        t->run(buf);//启动一个新的线程
    }
}

创建了一个PoolThread对象t,调用它的成员函数run来启动一个新的线程。

PoolThread类继承了线程类Thread,并且重写了它的线程入口成员函数threadLoop,因此当一个PoolThread对象t所对应的线程启动起来之后,它的成员函数threadLoop就会被调用。实现如下:

~/Android/frameworks/base/libs/binder

----ProcessState.cpp

class PoolThread : public Thread
{
public:
    PoolThread(bool isMain)
        : mIsMain(isMain)//isMain为true
    {
    }

protected:
    virtual bool threadLoop()
    {
        IPCThreadState::self()->joinThreadPool(mIsMain);//isMain为true
        return false;
    }

    const bool mIsMain;
};

和主线程一样调用了IPCThreadState类的成员函数joinThreadPool。实现如下:

~/Android/frameworks/base/libs/binder

----IPCThreadState.cpp

void IPCThreadState::joinThreadPool(bool isMain)//默认值为true
{
    .........

    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);//isMain为true,BC_ENTER_LOOPER

    ........

    status_t result;
    do {
        int32_t cmd;

        .......
        result = talkWithDriver();//将自己注册到Binder线程池中,一个无线循环中不断等待进程间通信请求
        if (result >= NO_ERROR) {
            size_t IN = mIn.dataAvail();
            if (IN < sizeof(int32_t)) continue;
            cmd = mIn.readInt32();
            ........

            result = executeCommand(cmd);//处理进程间通信请求
        }

       .........
        if(result == TIMED_OUT && !isMain) {//一直为false,因为isMain为true
            break;
        }
    } while (result != -ECONNREFUSED && result != -EBADF);

    ........

    mOut.writeInt32(BC_EXIT_LOOPER);//退出Binder线程池
    talkWithDriver(false);
}

参数isMain是一个默认参数,它的默认值为true。从前面的调用过程可以知道,无论是FregServer进程的主线程,还是FregServer进程刚才所创建的线程,它们都是主动(isMain为true)请求加入到Binder线程池的,即它们都不是由于Binder驱动程序请求创建而加入到Binder线程池的。

一个Binder线程的生命周期可以划分为三个阶段:

第一阶段是将自己注册到Binder线程池中;

第二阶段是一个无线循环中不断等待和处理进程间通信请求;

第三阶段是退出Binder线程池。

最后执行完的结果是FregServer有两个线程,睡眠等待进程间通信数据的到来。

Android Binder进程间通信---注册Service组件---启动Binder线程池

时间: 2024-11-10 18:10:10

Android Binder进程间通信---注册Service组件---启动Binder线程池的相关文章

Android Binder进程间通信---注册Service组件---发送和处理BC_REPLY返回协议

本文参考<Android系统源代码情景分析>,作者罗升阳 一.测试代码: -/Android/external/binder/server ----FregServer.cpp ~/Android/external/binder/common ----IFregService.cpp ----IFregService.h ~/Android/external/binder/client ----FregClient.cpp Binder库(libbinder)代码: ~/Android/fra

Android Binder进程间通信---注册Service组件---Server处理BC_TRANSACTION

这是我参照之前在iOS项目中用过的一个不规则形状按钮的第三方Button,这里用Cocos2d-x实现一个相似功能的按钮. 原文地址:http://blog.csdn.net/qqmcy/article/details/26161339 代码下载:http://download.csdn.net/detail/qqmcy/7365843 使用方法: .h // // TestScene.h // maptest // // Created by 杜甲 on 14-5-18. // // #ifn

Android Binder进程间通信---注册Service组件---封装进程间通信数据

本文参考<Android系统源代码情景分析>,作者罗升阳 一.测试代码: -/Android/external/binder/server ----FregServer.cpp ~/Android/external/binder/common ----IFregService.cpp ----IFregService.h ~/Android/external/binder/client ----FregClient.cpp Binder库(libbinder)代码: ~/Android/fra

Android Binder进程间通信---注册Service组件---发送和处理BC_TRANSACTION

本文参考<Android系统源代码情景分析>,作者罗升阳 一.测试代码: -/Android/external/binder/server ----FregServer.cpp ~/Android/external/binder/common ----IFregService.cpp ----IFregService.h ~/Android/external/binder/client ----FregClient.cpp Binder库(libbinder)代码: ~/Android/fra

Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6629298 在前面一篇文章浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路中, 介绍了在Android系统中Binder进程间通信机制中的Server角色是如何获得Service Manager远程接口的,即defaultServiceManager函数的实现.S

Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6633311 在上一篇文章中,我 们分析了Android系统进程间通信机制Binder中的Server在启动过程使用Service Manager的addService接口把自己添加到Service Manager守护过程中接受管理.在这一篇文章中,我们将深入到Binder驱动程序源代码去分析Client是如何通过Service Manager的

浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6627260 在前面一篇文章浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路中,介绍了Service Manager是如何成为Binder机制的守护进程的.既然作为守护进程,Service Manager的职责当然就是为Server和Client服务了.那么,Server和Client如何获得S

Android笔记二十七.Service组件入门(一).什么是Service?

转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 一.Service 1.Service简介 Service为Android四大组件之一,Service与Activity组件相似,都代表可执行的程序且有自己的生命周期,唯一的区别是Activity组件提供界面方便人机交互而Service只在后台运行且没有交互界面.Service是android 系统中的一种组件,它们都是从Context派生出来的,但是它不能自己运行,只能在后台运行,并且可以和其

JAVA线程池原理源码解析—为什么启动一个线程池,提交一个任务后,Main方法不会退出?

起因 public static void main(String[] args) { ExecutorService service = Executors.newFixedThreadPool(10); service.submit(() -> System.out.println("Hello ")); System.out.println("World"); } 呵呵,执行结果谁都知道,显而易见结论线程池的创建的时候,第一次submit操作会创建Wor