Android-AIDL
本文最后更新于 659 天前
1. AIDL简单使用
2. in、out、inout的区别

in 表示客户端传入的参数 (如:book), 服务端可以完整接受到改对象,但对其修改不会会同步到 客户端传入的参数对象

out 表示客户端传入的参数 (如:book), 服务端接受到的对象为空对象,并且服务端重新new修改改对象,并不会影响客户端传入的参数对象

inout表示客户端传入的参数 (如:book), 服务端可以完整接受到改对象,并且对其修改会同步到 客户端传入的参数对象

// BookManager.aidl
    interface BookManager {
        //保证客户端与服务端是连接上的且数据传输正常
        List<Book> getBooks();

        //通过三种定位tag做对比试验,观察输出的结果
        Book addBookIn(in Book book);
        Book addBookOut(out Book book);
        Book addBookInout(inout Book book);
    }
    @Override
    public Book addBookIn(Book book) throws RemoteException {
        synchronized (this) {
            // xxx
            //这里修改了并不影响客户端book对象,客户端的参数对象book的price属性不会被修改为2333
            book.setPrice(2333);
            if (!mBooks.contains(book)) {
                mBooks.add(book);
            }
            return book;
        }
    }

    @Override
    public Book addBookOut(Book book) throws RemoteException {
        synchronized (this) {
            // xxx
            // 即使客户端传入的book对象不是空对象,这里的book也会是空对象
            if(book == null){
                Log.e(TAG , "Book is null in Out");
                book = new Book();
            }
            book.setPrice(2333);
            if (!mBooks.contains(book)) {
                mBooks.add(book);
            }
            return book;
        }
    }

    @Override
    public Book addBookInout(Book book) throws RemoteException {
        synchronized (this) {
            // xxx
            if(book == null){
                Log.e(TAG , "Book is null in Inout");
                book = new Book();
            }
            //这里修改了会影响客户端book对象,客户端的参数对象book的price属性也被修改为2333
            book.setPrice(2333);
            if (!mBooks.contains(book)) {
                mBooks.add(book);
            }
            return book;
        }
    }
3. oneway
interface IPlayer {
    oneway void start();//异步,假设执行2秒  异步不定义返回值,客户端不使用
    oneway void stop();//异步,假设执行2秒
    int getVolume();// 同步,假设执行1秒
}
interface IPlayer2 {
    oneway void start();//异步,假设执行2秒  异步不定义返回值,客户端不使用
    oneway void stop();//异步,假设执行2秒
    int getVolume();// 同步,假设执行1秒
}

两个进程 不能同时调用 IPlayer.start()和IPlayer.stop(), 需要排队执行
两个进程 能同时调用 IPlayer.start()和IPlayer2.stop(), 需要排队执行

异步调用和串行化处理。异步调用是指应用向 binder 驱动发送数据后不需要挂起线程等待 binder 驱动的回复,而是直接结束。像一些系统服务调用应用进程的时候就会使用 oneway,比如 AMS 调用应用进程启动 Activity,这样就算应用进程中做了耗时的任务,也不会阻塞系统服务的运行

串行化处理是指对于一个服务端的 AIDL 接口而言,所有的 oneway 方法不会同时执行,binder 驱动会将他们串行化处理,排队一个一个调用

挂起相当于 Thread 的 sleep,是真正的”休眠”,底层调用的是 wait_event_interruptible() Linux 系统函数。Handler 机制的时候,Handler 中最关键的地方就是 Looper 的阻塞与唤醒,阻塞是调用了 nativePollOnce() 方法

/**
 * binder_proc_transaction() - sends a transaction to a process and wakes it up
 * @t:      transaction to send
 * @proc:   process to send the transaction to
 * @thread: thread in @proc to send the transaction to (may be NULL)
 */
static bool binder_proc_transaction(struct binder_transaction *t,
                    struct binder_proc *proc,
                    struct binder_thread *thread)
{
    //找到Server端的对应Binder服务在Binder驱动中对应的对象binder_node
    struct binder_node *node = t->buffer->target_node;
    //判断这次Binder调用是不是oneway
    bool oneway = !!(t->flags & TF_ONE_WAY);
    //初始化为false,用于标记当前Server端的对应Binder服务是否正在执行oneway的方法
    bool pending_async = false;

    binder_node_lock(node);
    //oneway == true
    if (oneway) {
        if (node->has_async_transaction) {
            //第2次oneway调用执行这里
            //发现对应Binder服务正在执行oneway的方法,设置pending_async为true
            pending_async = true;
        } else {
            //第1次oneway调用执行这里
            //发现对应Binder服务没有执行oneway的方法,设置has_async_transaction为1
            node->has_async_transaction = 1;
        }
    }

    binder_inner_proc_lock(proc);

    //如果发现Server端已经死亡,就直接返回了,正常不会执行
    if (proc->is_dead || (thread && thread->is_dead)) {
        binder_inner_proc_unlock(proc);
        binder_node_unlock(node);
        return false;
    }

    //oneway的调用thread为空,第1次oneway调用,pending_async为false
    if (!thread && !pending_async)
        //第1次oneway调用会找到一个空闲的Server端线程,用于响应这次oneway调用
        thread = binder_select_thread_ilocked(proc);

    if (thread) {
        //第1次oneway调用,thread不为空,直接把这次Binder work放到thread的工作队列去执行
        binder_enqueue_thread_work_ilocked(thread, &t->work);
    } else if (!pending_async) {
        binder_enqueue_work_ilocked(&t->work, &proc->todo);
    } else {
        //第2次oneway调用,thread为空,pending_async为true,
        //这次Binder work放到Binder Node的async_todo队列中,不会立刻执行
        binder_enqueue_work_ilocked(&t->work, &node->async_todo);
    }

    if (!pending_async)
        //第1次oneway调用,thread不为空,所以需要唤醒thread执行工作队列中的Binder work
        binder_wakeup_thread_ilocked(proc, thread, !oneway /* sync */);

    binder_inner_proc_unlock(proc);
    binder_node_unlock(node);

    return true;
}

释放与唤醒下一个任务

        case BC_FREE_BUFFER: {
            //准确释放进程B申请的buffer
            if (buffer->async_transaction && buffer->target_node) {
                struct binder_node *buf_node;
                struct binder_work *w;
                //先拿到这块buffer处理的binder node,也就是IPlayer1对应的binder node
                buf_node = buffer->target_node;
                binder_node_inner_lock(buf_node);
                //检查一下buf_node是否有未处理的oneway的binder work
                w = binder_dequeue_work_head_ilocked(
                        &buf_node->async_todo);
                if (!w) {
                    //不执行
                    buf_node->has_async_transaction = 0;
                } else {
                    //如果有未处理完的oneway的binder work,就将binder node保存的async_todo全部添加到进程A的todo。
                    binder_enqueue_work_ilocked(
                            w, &proc->todo);
                    //唤醒一个线程去处理todo中的binder work,也就是进程C的IPlayer1.start()
                    binder_wakeup_proc_ilocked(proc);
                }
                binder_node_inner_unlock(buf_node);
            }
            //释放进程B申请的buffer
            trace_binder_transaction_buffer_release(buffer);
            binder_transaction_buffer_release(proc, buffer, NULL);
            binder_alloc_free_buf(&proc->alloc, buffer);
            break;
        }
iichen:https://iichen.cn/?p=434
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇