利用putBinder实现跨进程传输大图片

在 Android 中,使用 putBinder 方法将实现了 IBinder 接口的对象传递到 Bundle 中,并通过 Intent 传递数据。以下是一个完整的示例,展示如何通过 putBinder 方法在跨进程传输大图片时实现这一目标。

步骤1:定义 AIDL 接口

首先,创建一个 AIDL 接口,用于定义获取 Bitmap 的方法。在你的应用模块中创建一个新的 AIDL 文件(例如 IRemoteCaller.aidl)。

package com.example.myapp;

import android.graphics.Bitmap;

interface IRemoteCaller {
   
   
    Bitmap getBitmap();
}

步骤2:实现 AIDL 接口

在服务端实现 AIDL 接口,并返回 Bitmap 对象。

服务端代码

public class ImageService extends Service {
   
   
    private Bitmap mBitmap;

    @Override
    public void onCreate() {
   
   
        super.onCreate();
        // 初始化 Bitmap,例如从文件中加载
        mBitmap = BitmapFactory.decodeFile(getExternalFilesDir(null) + "/shared_image.jpg");
    }

    private 
在接收端(`HeatmapOverviewActivity`)中,你需要通过`Intent`获取`Bundle`,然后从`Bundle`中提取`Binder`对象,并将其转换回原始类型(`FloorBeanBinder`)。以下是具体步骤和代码示例: --- ### **1. 接收端代码(HeatmapOverviewActivity)** ```kotlin class HeatmapOverviewActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 从Intent中获取Bundle val bundle = intent.extras ?: return // 从Bundle中获取Binder对象 val floorBeanBinder = bundle.getBinder(PageConstant.FLOOR_PLAN_INFO) as? FloorBeanBinder // 使用Binder中的数据 floorBeanBinder?.let { binder -> val floorPlanInfo = binder.getFloorPlanInfo() // 假设FloorBeanBinder有此方法 // 处理floorPlanInfo... } } } ``` --- ### **2. 关键点说明** 1. **`getBinder()`方法**: - `Bundle`提供了`getBinder(key: String)`方法,用于提取通过`putBinder()`存入的`IBinder`对象。 - 需要强制转换为目标类型(如`FloorBeanBinder`)。 2. **`FloorBeanBinder`的实现**: - 确保`FloorBeanBinder`实现了`Binder`接口,并提供了获取原始数据的方法(如`getFloorPlanInfo()`)。 - 示例实现: ```kotlin class FloorBeanBinder(private val floorPlanInfo: FloorPlanInfo) : Binder() { fun getFloorPlanInfo(): FloorPlanInfo = floorPlanInfo } ``` 3. **空安全处理**: - 使用`as?`安全转换,避免类型不匹配导致的`ClassCastException`。 - 检查`intent.extras`是否为`null`(如`?: return`)。 --- ### **3. 完整流程示例** #### **发送端(当前代码)** ```kotlin val intent = Intent(this, HeatmapOverviewActivity::class.java) val bundle = Bundle() bundle.putBinder(PageConstant.FLOOR_PLAN_INFO, FloorBeanBinder(getElementOperateDelegate().exportFloorPlanInfo())) intent.putExtras(bundle) startActivity(intent) ``` #### **接收端(HeatmapOverviewActivity)** ```kotlin class HeatmapOverviewActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_heatmap_overview) // 1. 获取Bundle val bundle = intent.extras ?: return // 2. 提取Binder并转换类型 val binder = bundle.getBinder(PageConstant.FLOOR_PLAN_INFO) as? FloorBeanBinder if (binder != null) { // 3. 使用数据 val floorPlanInfo = binder.getFloorPlanInfo() Log.d("Heatmap", "Received FloorPlanInfo: $floorPlanInfo") } else { Log.e("Heatmap", "FloorBeanBinder is null!") } } } ``` --- ### **4. 注意事项** 1. **跨进程通信(IPC)**: - 如果`HeatmapOverviewActivity`在不同进程,`Binder`需要实现`Parcelable`或使用`AIDL`。 - 简单场景(同进程)可直接使用`Binder`子类。 2. **性能优化**: - 避免通过`Binder`传递型数据(如Bitmap),改用文件路径或全局单例。 3. **Key的一致性**: - 确保`PageConstant.FLOOR_PLAN_INFO`在发送和接收端是相同的字符串常量。 --- ### **5. 替代方案(推荐)** 如果数据不需要跨进程,可以直接传递`Parcelable`对象(更简单高效): ```kotlin // 发送端 intent.putExtra("floor_info", getElementOperateDelegate().exportFloorPlanInfo()) // 接收端 val floorInfo = intent.getParcelableExtra<FloorPlanInfo>("floor_info") ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彬_小彬

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值