Android4.0 Bitmap Parcel传输源码分析

本文分析了Android 4.0之前和之后Bitmap通过Parcel传输的差异。在4.0之前,由于 Binder 的大小限制,大图片传输可能导致错误。4.0之后引入Blob,利用ashmem处理大对象,解决了大小限制问题。总结思考指出,4.0后直接传递图片在内存效率上优于保存到SD卡再传递。
摘要由CSDN通过智能技术生成

很久之前就看到有网友遇到用Parcel传Bitmap的时候,会遇到因为图片太大而报错,都在讨论传输Bitmap的时候的大小限制,但是实际上应该只有在4.0之前会有限制,4.0之后图片传输的方式有变化,它采用了Blob来传输,最终会使用ashmem来传递占用内存大的数据。下面分别介绍4.0前后Parcel对图片传输的异同。

Parcel写入读取

先简单介绍一下Parcel的写入读取模式,Parcel是Android中跨进程数据传递的中介,跨进程数据使用Parcel传递效率会比Serializable。Parcel提供了很多接口,比如writeInt,writeFloat,writeString,readInt,readFloat,readString等等,用这些接口可以读取写入数据.而实际上,Parcel里面有一个mData变量:

void* mData;

这个变量是一个指针类型,那些写入的接口都是将数据写入到这个指针变量指向的区域,读取也是从mData中读,写入和读取的数据相互对应。然后再将这个mData传入到Binder,或者是从Binder中读取出来。

2.3源码

在2.3中,Android Parcel传输图片是有大小限制的,实际上的限制应该是Binder对传输的数据大小的限制。Bitmap会对应的native层Parcel传输函数是Bitmap_writeToParcel,先看源码是怎么传输的:

static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject,
                                     const SkBitmap* bitmap,
                                     jboolean isMutable, jint density,
                                     jobject parcel) {
    if (parcel == NULL) {
        SkDebugf("------- writeToParcel null parcel\n");
        return false;
    }

    android::Parcel* p = android::parcelForJavaObject(env, parcel);

    p->writeInt32(isMutable);
    p->writeInt32(bitmap->config());
    p->writeInt32(bitmap->width());
    p->writeInt32(bitmap->height());
    p->writeInt32(bitmap->rowBytes());
    p->writeInt32(density); //这些都是写入到Parcel的mData

    if (bitmap->getConfig() == SkBitmap::kIndex8_Config) {
        SkColorTable* ctable = bitmap->getColorTable();
        if (ctable != NULL) {
            int count = ctable->count();
            p->writeInt32(count);
            memcpy(p->writeInplace(count * sizeof(SkP
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值