当前位置: 代码网 > it编程>App开发>Android > Android Binder 详解与实践指南(最新推荐)

Android Binder 详解与实践指南(最新推荐)

2025年11月21日 Android 我要评论
android binder 详解与实践指南1. binder 基础概念1.1 什么是 binder?binder 是 android 系统中最重要的进程间通信(ipc)机制,它具有以下特点:高性能:

android binder 详解与实践指南

1. binder 基础概念

1.1 什么是 binder?

binder 是 android 系统中最重要的进程间通信(ipc)机制,它具有以下特点:

  • 高性能:相比其他 ipc 机制,binder 只需要一次数据拷贝
  • 安全性:基于 c/s 架构,支持身份验证
  • 面向对象:可以像调用本地方法一样调用远程方法

1.2 binder 架构组件

client process → binder driver → server process
     ↓                              ↓
binder proxy                  binder object

2. binder 基础实例

2.1 简单的 binder 服务端

// simplebinderservice.java
package com.example.binderdemo;
import android.app.service;
import android.content.intent;
import android.os.ibinder;
import android.os.remoteexception;
import android.util.log;
public class simplebinderservice extends service {
    private static final string tag = "simplebinderservice";
    // 定义 aidl 接口的实现
    private final isimpleservice.stub binder = new isimpleservice.stub() {
        @override
        public int add(int a, int b) throws remoteexception {
            log.d(tag, "add() called with: a = " + a + ", b = " + b);
            return a + b;
        }
        @override
        public string greet(string name) throws remoteexception {
            log.d(tag, "greet() called with: name = " + name);
            return "hello, " + name + "! from binder service";
        }
        @override
        public void senddata(datamodel data) throws remoteexception {
            log.d(tag, "senddata() called with: " + data.tostring());
            // 处理数据...
        }
    };
    @override
    public ibinder onbind(intent intent) {
        log.d(tag, "onbind() called");
        return binder;
    }
    @override
    public void oncreate() {
        super.oncreate();
        log.d(tag, "service created");
    }
    @override
    public void ondestroy() {
        super.ondestroy();
        log.d(tag, "service destroyed");
    }
}

2.2 定义 aidl 接口

// isimpleservice.aidl
package com.example.binderdemo;
// 定义数据模型
parcelable datamodel;
interface isimpleservice {
    int add(int a, int b);
    string greet(string name);
    void senddata(in datamodel data);
}

2.3 数据模型定义

// datamodel.java
package com.example.binderdemo;
import android.os.parcel;
import android.os.parcelable;
public class datamodel implements parcelable {
    public int id;
    public string message;
    public long timestamp;
    public datamodel() {}
    public datamodel(int id, string message) {
        this.id = id;
        this.message = message;
        this.timestamp = system.currenttimemillis();
    }
    protected datamodel(parcel in) {
        id = in.readint();
        message = in.readstring();
        timestamp = in.readlong();
    }
    public static final creator<datamodel> creator = new creator<datamodel>() {
        @override
        public datamodel createfromparcel(parcel in) {
            return new datamodel(in);
        }
        @override
        public datamodel[] newarray(int size) {
            return new datamodel[size];
        }
    };
    @override
    public int describecontents() {
        return 0;
    }
    @override
    public void writetoparcel(parcel dest, int flags) {
        dest.writeint(id);
        dest.writestring(message);
        dest.writelong(timestamp);
    }
    @override
    public string tostring() {
        return "datamodel{" +
                "id=" + id +
                ", message='" + message + '\'' +
                ", timestamp=" + timestamp +
                '}';
    }
}

2.4 客户端实现

// mainactivity.java
package com.example.binderdemo;
import android.content.componentname;
import android.content.context;
import android.content.intent;
import android.content.serviceconnection;
import android.os.bundle;
import android.os.ibinder;
import android.os.remoteexception;
import android.widget.button;
import android.widget.textview;
import androidx.appcompat.app.appcompatactivity;
public class mainactivity extends appcompatactivity {
    private static final string tag = "mainactivity";
    private isimpleservice simpleservice;
    private boolean isbound = false;
    private textview resulttext;
    private serviceconnection connection = new serviceconnection() {
        @override
        public void onserviceconnected(componentname name, ibinder service) {
            log.d(tag, "service connected");
            simpleservice = isimpleservice.stub.asinterface(service);
            isbound = true;
            updatestatus("service connected");
        }
        @override
        public void onservicedisconnected(componentname name) {
            log.d(tag, "service disconnected");
            simpleservice = null;
            isbound = false;
            updatestatus("service disconnected");
        }
    };
    @override
    protected void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        setcontentview(r.layout.activity_main);
        resulttext = findviewbyid(r.id.result_text);
        button bindbtn = findviewbyid(r.id.bind_btn);
        button unbindbtn = findviewbyid(r.id.unbind_btn);
        button testbtn = findviewbyid(r.id.test_btn);
        bindbtn.setonclicklistener(v -> bindservice());
        unbindbtn.setonclicklistener(v -> unbindservice());
        testbtn.setonclicklistener(v -> testservice());
    }
    private void bindservice() {
        intent intent = new intent(this, simplebinderservice.class);
        bindservice(intent, connection, context.bind_auto_create);
        updatestatus("binding service...");
    }
    private void unbindservice() {
        if (isbound) {
            unbindservice(connection);
            isbound = false;
            simpleservice = null;
            updatestatus("service unbound");
        }
    }
    private void testservice() {
        if (!isbound || simpleservice == null) {
            updatestatus("service not bound!");
            return;
        }
        new thread(() -> {
            try {
                // 测试加法
                int result = simpleservice.add(5, 3);
                string message = "5 + 3 = " + result;
                // 测试问候
                string greeting = simpleservice.greet("android developer");
                // 测试数据传输
                datamodel data = new datamodel(1, "test message");
                simpleservice.senddata(data);
                runonuithread(() -> updatestatus(
                    message + "\n" + 
                    greeting + "\n" +
                    "data sent: " + data.tostring()
                ));
            } catch (remoteexception e) {
                runonuithread(() -> updatestatus("error: " + e.getmessage()));
                log.e(tag, "remoteexception: ", e);
            }
        }).start();
    }
    private void updatestatus(string text) {
        resulttext.settext(text);
        log.d(tag, text);
    }
    @override
    protected void ondestroy() {
        super.ondestroy();
        if (isbound) {
            unbindservice();
        }
    }
}

2.5 布局文件

<!-- activity_main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">
    <button
        android:id="@+id/bind_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="bind service" />
    <button
        android:id="@+id/unbind_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="unbind service" />
    <button
        android:id="@+id/test_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="test service" />
    <textview
        android:id="@+id/result_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margintop="16dp"
        android:padding="16dp"
        android:background="#f0f0f0"
        android:text="status: not connected"
        android:textsize="14sp" />
</linearlayout>

2.6 androidmanifest 配置

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.binderdemo">
    <application
        android:allowbackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/apptheme">
        <activity android:name=".mainactivity">
            <intent-filter>
                <action android:name="android.intent.action.main" />
                <category android:name="android.intent.category.launcher" />
            </intent-filter>
        </activity>
        <service
            android:name=".simplebinderservice"
            android:enabled="true"
            android:exported="false" />
    </application>
</manifest>

3. 运行结果分析

首次运行应用:

mainactivity: status: not connected

点击 “bind service” 按钮:

simplebinderservice: service created
simplebinderservice: onbind() called
mainactivity: service connected
mainactivity: status: service connected

点击 “test service” 按钮:

simplebinderservice: add() called with: a = 5, b = 3
simplebinderservice: greet() called with: name = android developer
simplebinderservice: senddata() called with: datamodel{id=1, message='test message', timestamp=1641234567890}
mainactivity: 5 + 3 = 8
hello, android developer! from binder service
data sent: datamodel{id=1, message='test message', timestamp=1641234567890}

点击 “unbind service” 按钮:

simplebinderservice: service destroyed
mainactivity: service unbound

4. 高级 binder 特性

4.1 带回调的 binder 服务

// icallbackservice.aidl
package com.example.binderdemo;
interface icallbackservice {
    void registercallback(icallback callback);
    void unregistercallback(icallback callback);
    void starttask(int taskid);
}
interface icallback {
    void ontaskstarted(int taskid);
    void ontaskprogress(int taskid, int progress);
    void ontaskcompleted(int taskid, string result);
}

4.2 回调服务实现

// callbackbinderservice.java
public class callbackbinderservice extends service {
    private static final string tag = "callbackbinderservice";
    private final list<icallback> callbacks = new copyonwritearraylist<>();
    private final icallbackservice.stub binder = new icallbackservice.stub() {
        @override
        public void registercallback(icallback callback) throws remoteexception {
            if (callback != null && !callbacks.contains(callback)) {
                callbacks.add(callback);
                log.d(tag, "callback registered, total: " + callbacks.size());
            }
        }
        @override
        public void unregistercallback(icallback callback) throws remoteexception {
            callbacks.remove(callback);
            log.d(tag, "callback unregistered, total: " + callbacks.size());
        }
        @override
        public void starttask(int taskid) throws remoteexception {
            log.d(tag, "starting task: " + taskid);
            new taskexecutor(taskid).start();
        }
    };
    private class taskexecutor extends thread {
        private final int taskid;
        taskexecutor(int taskid) {
            this.taskid = taskid;
        }
        @override
        public void run() {
            try {
                // 通知任务开始
                for (icallback callback : callbacks) {
                    callback.ontaskstarted(taskid);
                }
                // 模拟任务执行
                for (int i = 0; i <= 100; i += 10) {
                    thread.sleep(200);
                    // 更新进度
                    for (icallback callback : callbacks) {
                        callback.ontaskprogress(taskid, i);
                    }
                }
                // 任务完成
                for (icallback callback : callbacks) {
                    callback.ontaskcompleted(taskid, "task " + taskid + " completed successfully");
                }
            } catch (exception e) {
                log.e(tag, "task execution failed", e);
            }
        }
    }
    @override
    public ibinder onbind(intent intent) {
        return binder;
    }
}

4.3 客户端回调处理

// 在 mainactivity 中添加回调处理
private icallback callback = new icallback.stub() {
    @override
    public void ontaskstarted(int taskid) throws remoteexception {
        runonuithread(() -> updatestatus("task " + taskid + " started"));
    }
    @override
    public void ontaskprogress(int taskid, int progress) throws remoteexception {
        runonuithread(() -> updatestatus("task " + taskid + " progress: " + progress + "%"));
    }
    @override
    public void ontaskcompleted(int taskid, string result) throws remoteexception {
        runonuithread(() -> updatestatus("task " + taskid + " completed: " + result));
    }
};
private void testcallbackservice() {
    if (callbackservice != null) {
        try {
            callbackservice.registercallback(callback);
            callbackservice.starttask(1);
        } catch (remoteexception e) {
            log.e(tag, "callback test failed", e);
        }
    }
}

5. binder 传输数据类型

5.1 支持的数据类型

类型说明示例
基本类型int, long, float, double, booleanint count = 10
string字符串string name = "android"
charsequence字符序列charsequence text
parcelable可序列化对象datamodel data
list列表list<string> names
map映射map<string, integer> scores

5.2 复杂数据模型示例

// usermodel.java
public class usermodel implements parcelable {
    public int userid;
    public string username;
    public list<string> permissions;
    public map<string, string> attributes;
    // parcelable 实现...
    @override
    public void writetoparcel(parcel dest, int flags) {
        dest.writeint(userid);
        dest.writestring(username);
        dest.writestringlist(permissions);
        dest.writemap(attributes);
    }
    protected usermodel(parcel in) {
        userid = in.readint();
        username = in.readstring();
        permissions = in.createstringarraylist();
        attributes = in.readhashmap(string.class.getclassloader());
    }
}

6. binder 最佳实践

6.1 性能优化

  1. 减少跨进程调用:批量处理数据,避免频繁的小数据调用
  2. 使用合适的参数方向
    • in: 客户端到服务端
    • out: 服务端到客户端
    • inout: 双向传输

6.2 错误处理

try {
    string result = remoteservice.dosomething(param);
    // 处理结果
} catch (remoteexception e) {
    // 处理通信错误
    log.e(tag, "remote call failed", e);
    // 重连或提示用户
} catch (securityexception e) {
    // 处理权限错误
    log.e(tag, "permission denied", e);
}

6.3 内存管理

// 及时注销回调,避免内存泄漏
@override
protected void ondestroy() {
    if (isbound && callbackservice != null) {
        try {
            callbackservice.unregistercallback(callback);
        } catch (remoteexception e) {
            // 忽略注销时的错误
        }
    }
    unbindservice(connection);
    super.ondestroy();
}

7. 总结

通过以上实例,你应该掌握了:

  1. binder 基础架构:理解 c/s 模式和 binder driver 的作用
  2. aidl 使用:学会定义接口和数据模型
  3. 服务实现:创建 binder 服务并处理客户端请求
  4. 客户端编程:绑定服务、调用远程方法、处理回调
  5. 数据传输:使用 parcelable 传输复杂数据
  6. 错误处理:妥善处理 remoteexception 等异常

binder 是 android 系统的核心 ipc 机制,熟练掌握 binder 对于开发系统服务、跨进程通信等高级功能至关重要。

到此这篇关于android binder 详解与实践指南的文章就介绍到这了,更多相关android binder内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com