`

Android IPC机制详解

阅读更多

o IBinder接口

IBinder接口是对跨进程的对象的抽象。普通对象在当前进程可以访问,如果希望对象能被其它进程访问,那就必须实现IBinder接口。IBinder接口可以指向本地对象,也可以指向远程对象,调用者不需要关心指向的对象是本地的还是远程。

transact是IBinder接口中一个比较重要的函数,它的函数原型如下:

virtual status_t transact(
uint32_t code,
 const
 Parcel&
 data,
 Parcel*
 reply,
 uint32_t flags =
 0
)
 =
 0
;

android中的IPC的基本模型是基于客户/服务器(C/S)架构的。

客户端 请求通过内核模块中转 服务端

如果IBinder指向的是一个客户端代理,那transact只是把请求发送给服务器。服务端的IBinder的transact则提供了实际的服务。

o 客户端

BpBinder是远程对象在当前进程的代理,它实现了IBinder接口。它的transact函数实现如下:

status_t BpBinder::
transact
(

    uint32_t code,
 const
 Parcel&
 data,
 Parcel*
 reply,
 uint32_t flags)

{

    // Once a binder has died, it will never come back to life.

    if
 (
mAlive)
 {

        status_t status =
 IPCThreadState::
self
(
)
->
transact(

            mHandle,
 code,
 data,
 reply,
 flags)
;

        if
 (
status ==
 DEAD_OBJECT)
 mAlive =
 0
;

        return
 status;

    }
 
 
    return
 DEAD_OBJECT;

}

参数说明:

  • code 是请求的ID号。
  • data 是请求的参数。
  • reply 是返回的结果。
  • flags 一些额外的标识,如FLAG_ONEWAY。通常为0。
  • transact只是简单的调用了IPCThreadState::self()的transact,在IPCThreadState::transact中:

    status_t IPCThreadState::
    transact
    (
    int32_t handle,
    
                                      uint32_t code,
     const
     Parcel&
     data,
    
                                      Parcel*
     reply,
     uint32_t flags)
    
    {
    
        status_t err =
     data.errorCheck
    (
    )
    ;
    
     
        flags |=
     TF_ACCEPT_FDS;
    
     
        IF_LOG_TRANSACTIONS(
    )
     {
    
            TextOutput::
    Bundle
     _b(
    alog)
    ;
    
            alog <<
     "BC_TRANSACTION thr "
     <<
     (
    void
    *
    )
    pthread_self(
    )
     <<
     " / hand "
    
                <<
     handle <<
     " / code "
     <<
     TypeCode(
    code)
     <<
     ": "
    
                <<
     indent <<
     data <<
     dedent <<
     endl;
    
        }
    
     
        if
     (
    err ==
     NO_ERROR)
     {
    
            LOG_ONEWAY(
    ">>>> SEND from pid %d uid %d %s"
    ,
     getpid(
    )
    ,
     getuid(
    )
    ,
    
                (
    flags &
     TF_ONE_WAY)
     ==
     0
     ?
     "READ REPLY"
     :
     "ONE WAY"
    )
    ;
    
            err =
     writeTransactionData(
    BC_TRANSACTION,
     flags,
     handle,
     code,
     data,
     NULL)
    ;
    
        }
    
     
        if
     (
    err !=
     NO_ERROR)
     {
    
            if
     (
    reply)
     reply->
    setError(
    err)
    ;
    
            return
     (
    mLastError =
     err)
    ;
    
        }
    
     
        if
     (
    (
    flags &
     TF_ONE_WAY)
     ==
     0
    )
     {
    
            if
     (
    reply)
     {
    
                err =
     waitForResponse(
    reply)
    ;
    
            }
     else
     {
    
                Parcel fakeReply;
    
                err =
     waitForResponse(
    &
    fakeReply)
    ;
    
            }
    
     
            IF_LOG_TRANSACTIONS(
    )
     {
    
                TextOutput::
    Bundle
     _b(
    alog)
    ;
    
                alog <<
     "BR_REPLY thr "
     <<
     (
    void
    *
    )
    pthread_self(
    )
     <<
     " / hand "
    
                    <<
     handle <<
     ": "
    ;
    
                if
     (
    reply)
     alog <<
     indent <<
     *
    reply <<
     dedent <<
     endl;
    
                else
     alog <<
     "(none requested)"
     <<
     endl;
    
            }
    
        }
     else
     {
    
            err =
     waitForResponse(
    NULL,
     NULL)
    ;
    
        }
    
     
        return
     err;
    
    }
    
     
    status_t IPCThreadState::
    waitForResponse
    (
    Parcel *
    reply,
     status_t *
    acquireResult)
    
    {
    
        int32_t cmd;
    
        int32_t err;
    
     
        while
     (
    1
    )
     {
    
            if
     (
    (
    err=
    talkWithDriver(
    )
    )
     <
     NO_ERROR)
     break
    ;
    
            err =
     mIn.errorCheck
    (
    )
    ;
    
            if
     (
    err <
     NO_ERROR)
     break
    ;
    
            if
     (
    mIn.dataAvail
    (
    )
     ==
     0
    )
     continue
    ;
    
     
            cmd =
     mIn.readInt32
    (
    )
    ;
    
     
            IF_LOG_COMMANDS(
    )
     {
    
                alog <<
     "Processing waitForResponse Command: "
    
                    <<
     getReturnString(
    cmd)
     <<
     endl;
    
            }
    
     
            switch
     (
    cmd)
     {
    
            case
     BR_TRANSACTION_COMPLETE:
    
                if
     (
    !
    reply &&
     !
    acquireResult)
     goto
     finish;
    
                break
    ;
    
     
            case
     BR_DEAD_REPLY:
    
                err =
     DEAD_OBJECT;
    
                goto
     finish;
    
     
            case
     BR_FAILED_REPLY:
    
                err =
     FAILED_TRANSACTION;
    
                goto
     finish;
    
     
            case
     BR_ACQUIRE_RESULT:
    
                {
    
                    LOG_ASSERT(
    acquireResult !=
     NULL,
     "Unexpected brACQUIRE_RESULT"
    )
    ;
    
                    const
     int32_t result =
     mIn.readInt32
    (
    )
    ;
    
                    if
     (
    !
    acquireResult)
     continue
    ;
    
                    *
    acquireResult =
     result ?
     NO_ERROR :
     INVALID_OPERATION;
    
                }
    
                goto
     finish;
    
     
            case
     BR_REPLY:
    
                {
    
                    binder_transaction_data tr;
    
                    err =
     mIn.read
    (
    &
    tr,
     sizeof
    (
    tr)
    )
    ;
    
                    LOG_ASSERT(
    err ==
     NO_ERROR,
     "Not enough command data for brREPLY"
    )
    ;
    
                    if
     (
    err !=
     NO_ERROR)
     goto
     finish;
    
     
                    if
     (
    reply)
     {
    
                        if
     (
    (
    tr.flags
     &
     TF_STATUS_CODE)
     ==
     0
    )
     {
    
                            reply->
    ipcSetDataReference(
    
                                reinterpret_cast(
    tr.data
    .ptr
    .buffer
    )
    ,
    
                                tr.data_size
    ,
    
                                reinterpret_cast(
    tr.data
    .ptr
    .offsets
    )
    ,
    
                                tr.offsets_size
    /
    sizeof
    (
    size_t)
    ,
    
                                freeBuffer,
     this)
    ;
    
                        }
     else
     {
    
                            err =
     *
    static_cast(
    tr.data
    .ptr
    .buffer
    )
    ;
    
                            freeBuffer(
    NULL,
    
                                reinterpret_cast(
    tr.data
    .ptr
    .buffer
    )
    ,
    
                                tr.data_size
    ,
    
                                reinterpret_cast(
    tr.data
    .ptr
    .offsets
    )
    ,
    
                                tr.offsets_size
    /
    sizeof
    (
    size_t)
    ,
     this)
    ;
    
                        }
    
                    }
     else
     {
    
                        freeBuffer(
    NULL,
    
                            reinterpret_cast(
    tr.data
    .ptr
    .buffer
    )
    ,
    
                            tr.data_size
    ,
    
                            reinterpret_cast(
    tr.data
    .ptr
    .offsets
    )
    ,
    
                            tr.offsets_size
    /
    sizeof
    (
    size_t)
    ,
     this)
    ;
    
                        continue
    ;
    
                    }
    
                }
    
                goto
     finish;
    
     
            default
    :
    
                err =
     executeCommand(
    cmd)
    ;
    
                if
     (
    err !=
     NO_ERROR)
     goto
     finish;
    
                break
    ;
    
            }
    
        }
    
     
    finish:
    
        if
     (
    err !=
     NO_ERROR)
     {
    
            if
     (
    acquireResult)
     *
    acquireResult =
     err;
    
            if
     (
    reply)
     reply->
    setError(
    err)
    ;
    
            mLastError =
     err;
    
        }
    
     
        return
     err;
    
    }
    

    这里transact把请求经内核模块发送了给服务端,服务端处理完请求之后,沿原路返回结果给调用者。这里也可以看出请求是同步操作,它会等待直到结果返回为止。

    在BpBinder之上进行简单包装,我们可以得到与服务对象相同的接口,调用者无需要关心调用的对象是远程的还是本地的。拿ServiceManager来说:
    (frameworks/base/libs/utils/IServiceManager.cpp)

    class BpServiceManager :
     public BpInterface
    {
    
    public:
    
        BpServiceManager(
    const
     sp&
     impl)
    
            :
     BpInterface(
    impl)
    
        {
    
        }
    
    ...
        virtual
     status_t addService(
    const
     String16&
     name,
     const
     sp&
     service)
    
        {
    
            Parcel data,
     reply;
    
            data.writeInterfaceToken
    (
    IServiceManager::
    getInterfaceDescriptor
    (
    )
    )
    ;
    
            data.writeString16
    (
    name)
    ;
    
            data.writeStrongBinder
    (
    service)
    ;
    
            status_t err =
     remote(
    )
    ->
    transact(
    ADD_SERVICE_TRANSACTION,
     data,
     &
    reply)
    ;
    
            return
     err ==
     NO_ERROR ?
     reply.readInt32
    (
    )
     :
     err;
    
        }
    
    ...
    }
    ;
    

    BpServiceManager实现了 IServiceManager和IBinder两个接口,调用者可以把BpServiceManager的对象看作是一个 IServiceManager对象或者IBinder对象。当调用者把BpServiceManager对象当作IServiceManager对象使 用时,所有的请求只是对BpBinder::transact的封装。这样的封装使得调用者不需要关心IServiceManager对象是本地的还是远 程的了。

    客户通过defaultServiceManager函数来创建BpServiceManager对象:
    (frameworks/base/libs/utils/IServiceManager.cpp)

    sp<
    IServiceManager>
     defaultServiceManager(
    )
    
    {
    
        if
     (
    gDefaultServiceManager !=
     NULL)
     return
     gDefaultServiceManager;
     
     
        {
    
            AutoMutex _l(
    gDefaultServiceManagerLock)
    ;
    
            if
     (
    gDefaultServiceManager ==
     NULL)
     {
    
                gDefaultServiceManager =
     interface_cast<
    IServiceManager>
    (
    
                    ProcessState::
    self
    (
    )
    ->
    getContextObject(
    NULL)
    )
    ;
    
            }
    
        }
     
     
        return
     gDefaultServiceManager;
    
    }
    

    先通过ProcessState::self()->getContextObject(NULL)创建一个Binder对象,然后通过 interface_cast和IMPLEMENT_META_INTERFACE(ServiceManager, “android.os.IServiceManager”)把Binder对象包装成 IServiceManager对象。原理上等同于创建了一个BpServiceManager对象。

    ProcessState::self()->getContextObject调用ProcessState::getStrongProxyForHandle创建代理对象:

    sp<
    IBinder>
     ProcessState::
    getStrongProxyForHandle
    (
    int32_t handle)
    
    {
    
        sp<
    IBinder>
     result;
     
     
        AutoMutex _l(
    mLock)
    ;
     
     
        handle_entry*
     e =
     lookupHandleLocked(
    handle)
    ;
     
     
        if
     (
    e !=
     NULL)
     {
    
            // We need to create a new BpBinder if there isn't currently one, OR we
    
            // are unable to acquire a weak reference on this current one.  See comment
    
            // in getWeakProxyForHandle() for more info about this.
    
            IBinder*
     b =
     e->
    binder;
    
            if
     (
    b ==
     NULL ||
     !
    e->
    refs->
    attemptIncWeak(
    this)
    )
     {
    
                b =
     new BpBinder(
    handle)
    ;
    
                e->
    binder =
     b;
    
                if
     (
    b)
     e->
    refs =
     b->
    getWeakRefs(
    )
    ;
    
                result =
     b;
    
            }
     else
     {
    
                // This little bit of nastyness is to allow us to add a primary
    
                // reference to the remote proxy when this team doesn't have one
    
                // but another team is sending the handle to us.
    
                result.force_set
    (
    b)
    ;
    
                e->
    refs->
    decWeak(
    this)
    ;
    
            }
    
        }
     
     
        return
     result;
    
    }
    

    如果handle为空,默认为context_manager对象,context_manager实际上就是ServiceManager。
    o 服务端
    服务端也要实现IBinder接口,BBinder类对IBinder接口提供了部分默认实现,其中transact的实现如下:

    status_t BBinder::
    transact
    (
    
        uint32_t code,
     const
     Parcel&
     data,
     Parcel*
     reply,
     uint32_t flags)
    
    {
    
        data.setDataPosition
    (
    0
    )
    ;
     
     
        status_t err =
     NO_ERROR;
    
        switch
     (
    code)
     {
    
            case
     PING_TRANSACTION:
    
                reply->
    writeInt32(
    pingBinder(
    )
    )
    ;
    
                break
    ;
    
            default
    :
    
                err =
     onTransact(
    code,
     data,
     reply,
     flags)
    ;
    
                break
    ;
    
        }
     
     
        if
     (
    reply !=
     NULL)
     {
    
            reply->
    setDataPosition(
    0
    )
    ;
    
        }
     
     
        return
     err;
    
    }
    

    PING_TRANSACTION请求用来检查对象是否还存在,这里简单的把 pingBinder的返回值返回给调用者。其它的请求交给onTransact处理。onTransact是BBinder里声明的一个 protected类型的虚函数,这个要求它的子类去实现。比如CameraService里的实现如下:

    status_t CameraService::
    onTransact
    (
    
        uint32_t code,
     const
     Parcel&
     data,
     Parcel*
     reply,
     uint32_t flags)
    
    {
    
        // permission checks...
    
        switch
     (
    code)
     {
    
            case
     BnCameraService::
    CONNECT
    :
    
                IPCThreadState*
     ipc =
     IPCThreadState::
    self
    (
    )
    ;
    
                const
     int
     pid =
     ipc->
    getCallingPid(
    )
    ;
    
                const
     int
     self_pid =
     getpid(
    )
    ;
    
                if
     (
    pid !=
     self_pid)
     {
    
                    // we're called from a different process, do the real check
    
                    if
     (
    !
    checkCallingPermission(
    
                            String16(
    "android.permission.CAMERA"
    )
    )
    )
    
                    {
    
                        const
     int
     uid =
     ipc->
    getCallingUid(
    )
    ;
    
                        LOGE(
    "Permission Denial: "
    
                                "can't use the camera pid=%d, uid=%d"
    ,
     pid,
     uid)
    ;
    
                        return
     PERMISSION_DENIED;
    
                    }
    
                }
    
                break
    ;
    
        }
    
     
        status_t err =
     BnCameraService::
    onTransact
    (
    code,
     data,
     reply,
     flags)
    ;
    
     
        LOGD(
    "+++ onTransact err %d code %d"
    ,
     err,
     code)
    ;
    
     
        if
     (
    err ==
     UNKNOWN_TRANSACTION ||
     err ==
     PERMISSION_DENIED)
     {
    
            // the 'service' command interrogates this binder for its name, and then supplies it
    
            // even for the debugging commands.  that means we need to check for it here, using
    
            // ISurfaceComposer (since we delegated the INTERFACE_TRANSACTION handling to
    
            // BnSurfaceComposer before falling through to this code).
    
     
            LOGD(
    "+++ onTransact code %d"
    ,
     code)
    ;
    
     
            CHECK_INTERFACE(
    ICameraService,
     data,
     reply)
    ;
    
     
            switch
    (
    code)
     {
    
            case
     1000
    :
    
            {
    
                if
     (
    gWeakHeap !=
     0
    )
     {
    
                    sp h =
     gWeakHeap.promote
    (
    )
    ;
    
                    IMemoryHeap *
    p =
     gWeakHeap.unsafe_get
    (
    )
    ;
    
                    LOGD(
    "CHECKING WEAK REFERENCE %p (%p)"
    ,
     h.get
    (
    )
    ,
     p)
    ;
    
                    if
     (
    h !=
     0
    )
    
                        h->
    printRefs(
    )
    ;
    
                    bool attempt_to_delete =
     data.readInt32
    (
    )
     ==
     1
    ;
    
                    if
     (
    attempt_to_delete)
     {
    
                        // NOT SAFE!
    
                        LOGD(
    "DELETING WEAK REFERENCE %p (%p)"
    ,
     h.get
    (
    )
    ,
     p)
    ;
    
                        if
     (
    p)
     delete p;
    
                    }
    
                    return
     NO_ERROR;
    
                }
    
            }
    
            break
    ;
    
            default
    :
    
                break
    ;
    
            }
    
        }
    
        return
     err;
    
    }
    

    由此可见,服务端的onTransact是一个请求分发函数,它根据请求码(code)做相应的处理。

    o 消息循环

    服务端(任何进程都可以作为服务端)有一个线程监听来自客户端的请求,并循环处理这些请求。

    如果在主线程中处理请求,可以直接调用下面的函数:

    IPCThreadState::
    self
    (
    )
    ->
    joinThreadPool(
    mIsMain)
    ;
    

    如果想在非主线程中处理请求,可以按下列方式:

            sp
     proc =
     ProcessState::
    self
    (
    )
    ;
    
            if
     (
    proc->
    supportsProcesses(
    )
    )
     {
    
                LOGV(
    "App process: starting thread pool.\n
    "
    )
    ;
    
                proc->
    startThreadPool(
    )
    ;
    
            }
    

    startThreadPool的实现原理:

    void
     ProcessState::
    startThreadPool
    (
    )
    
    {
    
        AutoMutex _l(
    mLock)
    ;
    
        if
     (
    !
    mThreadPoolStarted)
     {
    
            mThreadPoolStarted =
     true
    ;
    
            spawnPooledThread(
    true
    )
    ;
    
        }
    
    }
     
     
    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
     t =
     new PoolThread(
    isMain)
    ;
    
            t->
    run(
    buf)
    ;
    
        }
    
    }
    

    这里创建了PoolThread的对象,实现上就是创建了一个线程。所有的线程类都要实现threadLoop虚函数。PoolThread的threadLoop的实现如下:

        virtual bool threadLoop(
    )
    
        {
    
            IPCThreadState::
    self
    (
    )
    ->
    joinThreadPool(
    mIsMain)
    ;
    
            return
     false
    ;
    
        }
    

    上述代码,简而言之就是创建了一个线程,然后在线程里调用 IPCThreadState::self()->joinThreadPool函数。

    下面再看joinThreadPool的实现:

    do
    
    {
    
    ...
            result
     =
     talkWithDriver(
    )
    ;
    
            if
     (
    result >=
     NO_ERROR)
     {
    
                size_t IN =
     mIn.dataAvail
    (
    )
    ;
    
                if
     (
    IN <
     sizeof
    (
    int32_t)
    )
     continue
    ;
    
                cmd =
     mIn.readInt32
    (
    )
    ;
    
                IF_LOG_COMMANDS(
    )
     {
    
                    alog <<
     "Processing top-level Command: "
    
                        <<
     getReturnString(
    cmd)
     <<
     endl;
    
                }
    
                result =
     executeCommand(
    cmd)
    ;
    
            }
    
    ...
    while
    (
    ...)
    ;
    

    这个函数在循环中重复执行下列动作:

    1. talkWithDriver 通过ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)读取请求和写回结果。
    2. executeCommand 执行相应的请求

    在IPCThreadState::executeCommand(int32_t cmd)函数中:

    1. 对于控制对象生命周期的请求,像BR_ACQUIRE/BR_RELEASE直接做了处理。
    2. 对于BR_TRANSACTION请求,它调用被请求对象的transact函数。

    按下列方式调用实际的对象:

    if
     (
    tr.target
    .ptr
    )
     {
    
        sp<
    BBinder>
     b(
    (
    BBinder*
    )
    tr.cookie
    )
    ;
    
        const
     status_t error =
     b->
    transact(
    tr.code
    ,
     buffer,
     &
    reply,
     0
    )
    ;
    
        if
     (
    error <
     NO_ERROR)
     reply.setError
    (
    error)
    ;
     
     
    }
     else
     {
    
        const
     status_t error =
     the_context_object->
    transact(
    tr.code
    ,
     buffer,
     &
    reply,
     0
    )
    ;
    
        if
     (
    error <
     NO_ERROR)
     reply.setError
    (
    error)
    ;
    
    }
    

    如果tr.target.ptr不为空,就把tr.cookie转换成一个Binder对象,并调用它的transact函数。如果没有目标对象, 就调用 the_context_object对象的transact函数。奇怪的是,根本没有谁对the_context_object进行初始 化,the_context_object是空指针。原因是context_mgr的请求发给了ServiceManager,所以根本不会走到else 语句里来。

    o 内核模块

    android使用了一个内核模块binder来中转各个进程之间的消息。模块源代码放在binder.c里,它是一个字符驱动程序,主要通过 binder_ioctl与用户空间的进程交换数据。其中BINDER_WRITE_READ用来读写数据,数据包中有一个cmd域用于区分不同的请求:

    1. binder_thread_write用于发送请求或返回结果。
    2. binder_thread_read用于读取结果。

    从binder_thread_write中调用binder_transaction中转请求和返回结果,binder_transaction的实现如下:

    对请求的处理:

    1. 通过对象的handle找到对象所在的进程,如果handle为空就认为对象是context_mgr,把请求发给context_mgr所在的进程。
    2. 把请求中所有的binder对象全部放到一个RB树中。
    3. 把请求放到目标进程的队列
      分享到:
      评论

    相关推荐

      Android IPC.docx

      ### Android IPC机制详解 #### 一、概述 Android IPC(Inter-Process Communication)是指在Android系统中不同进程间进行通信的机制。为了确保应用程序的安全性和稳定性,Android将每个应用运行在一个独立的进程中...

      android IPC及原理简介

      ### Android IPC 及其...Android的IPC机制主要依赖于Binder,这是一种高效且易于使用的进程间通信方式。通过了解Binder的工作原理、实现步骤以及注意事项,开发者可以更好地利用这一机制构建出高效稳定的Android应用。

      Android IPC机制Messenger实例详解

      "Android IPC机制Messenger实例详解" Android IPC机制Messenger实例详解是Android操作系统中的一种进程间通信机制,通过Messenger对象可以在不同进程间传递Message对象,从而实现进程间的数据传递。Messenger使用...

      Android的IPC与AIDL

      Android的IPC机制是其架构设计中的一个重要组成部分,它不仅提高了应用的安全性和灵活性,还增强了系统的整体性能。通过深入理解IPC机制,开发者可以更加灵活地构建复杂的应用程序,实现高效稳定的通信。

      AndroidBinder机制总结[归纳].pdf

      在Android系统中,Binder机制是实现进程间通信(IPC)的核心工具,尤其在跨应用程序组件交互时至关重要。本文将深入探讨Android Binder机制及其在组件化思想中的应用。 1. Android组件化思想 Android应用的组件化...

      Android Binder机制

      Android Binder机制是Android系统的核心组件之一,它负责进程间通信(IPC,Inter-Process Communication),使得不同应用程序或者同一系统中的不同组件能够有效地交互。在Android系统中,由于每个应用程序运行在自己...

      Binder Android IPC Linux 内核 驱动

      相比于传统的IPC机制,Binder在数据传输过程中仅涉及一次拷贝操作,这大大提高了通信效率。具体来说,数据直接从发送方的缓存区拷贝到接收方的缓存区,中间没有经过额外的缓冲区。 #### 五、Binder的安全性 ##### ...

      Android AIDL使用详解

      Android AIDL(Android Interface Definition Language)是Android系统提供的一种接口定义语言,用于处理不同进程间的通信(IPC: Interprocess Communication)。在Android应用开发中,当需要在不同的应用程序组件...

      android O rild详解

      ### Android O RIL 架构详解 #### Treble 概述 随着移动设备市场的迅速扩张和技术的不断进步,Google 在 Android O 版本中引入了一项重大的软件架构改进——Treble(三重奏)。这一举措旨在降低原始设计制造商 (ODM...

      Android应用开发详解2

      Binder机制是Android独特的进程间通信(IPC)方式,它允许不同进程间的对象交互,确保了系统服务的高效运行。以下是对每个压缩包文件中可能包含的知识点的详细解释: 1. **Binder16.rar**:可能涵盖了Android ...

      Android进程间通信-Binder机制详解

      【Android 进程间通信-Binder 机制详解】 在Android系统中,进程间通信(IPC,Inter-Process Communication)是实现不同应用程序组件协同工作的关键。Binder机制是Android独有的IPC方式,它不同于传统的Unix/Linux...

      详解Android跨进程IPC通信AIDL机制原理

      Android 跨进程 IPC 通信 AIDL 机制原理 Android Interface Definition Language(AIDL)是一种用于生成 Android 不同进程间进行进程通信(IPC)的代码机制。AIDL IPC 机制是面向接口的,像 COM 或 Corba 一样,...

      Android各组件详解

      - **Binder IPC驱动**:Binder机制是Android中进程间通信的基础。 - **电源管理(Power Management)**:管理设备的电量,实现节能模式等功能。 #### 三、Android应用程序 Android应用程序是由多个组件组成的,每...

      Android 提高篇 机制 分析

      - **Binder**:基础的IPC机制。 - **ServiceManager**:管理所有服务的中心点。 - **Service**:具体的服务实例。 #### 七、Service深入分析 针对Service组件进行了更深层次的研究,探讨其生命周期、工作方式以及...

      android之AIDL详解demo1

      在Android系统中,进程间的通信(IPC,Inter-Process Communication)是实现组件间协同工作的重要机制。当一个应用需要与另一个应用的组件进行交互时,就需要用到IPC。AIDL(Android Interface Definition Language...

      Android-framework详解

      - **简介**:Binder是Android IPC(进程间通信)的核心机制,用于实现跨进程的数据交换和服务调用。 - **工作原理**:通过创建Binder对象并将其注册到ServiceManager中,其他进程可以通过查找该服务名来获取Binder...

      android各组件详解- Service

      Service不仅可以在同一进程中运行,还能跨越进程边界进行调用,这是通过Android提供的轻量级IPC机制实现的。当一个方法在本地进程调用,而实际执行却发生在另一个远程进程时,系统会自动将方法调用和相关参数序列化...

    Global site tag (gtag.js) - Google Analytics