JavaBinder: !!! FAILED BINDER TRANSACTION !!! 异常的解决方案分析

JavaBinder: !!! FAILED BINDER TRANSACTION !!! 异常的解决方案分析

出现的缘由

本人一直负责公司车机端多媒体app软件的开发工作,最近负责的一个项目的情形是:在A Activity读取外接U盘中的图片文件,封装:

public class MediaFileBean implements Serializable {
private static final long serialVersionUID = 1L;
private String name = "";
private String time = "";
private String path = "";
private Bitmap bitmap;//图片第一帧,即缩略图
private String fileName = "";
private int isLove = -1;
private FileFormat fileFormate;
private String sortLetters;

    ......
}

并以列表显示缩略图,当点击显示图片时,再把所有的数据传递给B(专门用于显示图片):

AActivity.java:
private void enterBActivity(ArrayList mPhotoList, int position) {
    Intent intent = new Intent(mActivity, BActivity.class);
    intent.putExtra(Constants.PHOTO_ITEM_LIST, mPhotoList);//将扫描出来的图片文件传递给B
    intent.putExtra(Constants.PHOTO_CURRENT_POSITION, position);
    startActivity(intent);
}

B中接收A发来的数据:

//onCreate()中调用initData()
public void initData() {
    ......
    mPhotoList = (ArrayList) getIntent().getSerializableExtra(Constants.PHOTO_ITEM_LIST);
    currentPosition = getIntent().getIntExtra(Constants.PHOTO_CURRENT_POSITION, -1);
    ......
}

可是如果U盘中含有大量的图片时,无论怎么点,就是进不去B页面,程序也不crash,后台打印logcat,发现出现 JavaBinder: !!! FAILED BINDER TRANSACTION !!! 错误

出现的原因

网上搜索了一遍,大致的原因就是用Intent传递数据时,Bitmap不能大于40KB,而根据官网的介绍,Intent传递数据有限制,最大为1M左右

解决的办法

1.尽可能的不再Intent中传递Bitmap。可以先把要传递的bitmap保存在SD中,Intent中传递时用url地址代替。

2.如果实在要对Bitmap进行传递,可以先对其压缩

`/**
 * 压缩图片
 * 该方法引用自:http://blog.csdn.net/demonliuhui/article/details/52949203
 * @param image
 * @return
 */
public static Bitmap compressImage(Bitmap image) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
    int options = 100;
    while (baos.toByteArray().length / 1024 > 100) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩
        baos.reset();//重置baos即清空baos
        image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
        options -= 10;//每次都减少10
    }
    ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
    Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
    return bitmap;
}`

3.将要传递的数据改成全局变量

如果要传递的量大,上述的方法2也是于事无补的。比如说我的上述问题,即使在bean中去掉bitmap变量,还是会报错,因为我要传递的数组实在太大了!换一种思路,将要传递的数据放在一个固定的生命周期中的值里,随时赋值随时取值,想到这,放在Application中很合适:

public class MediaApplication extends Application {
    // 用于传递的图片数据
    private List mPhotoList;
    private static MediaApplication mInstance;
    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }

    public synchronized static MediaApplication getInstance() {
        return mInstance;
    }

    public void setPhotoList(ArrayList list){
        this.mPhotoList = list;
    }

    public List getPhotoList(){
        return this.mPhotoList;
    }

}

A向B跳转时改为:

private void enterBActivity(ArrayList mPhotoList, int position) {
    MediaApplication.getInstance().setPhotoList(mPhotoList);
    Intent intent = new Intent(mActivity, BActivity.class);
    intent.putExtra(Constants.PHOTO_CURRENT_POSITION, position);
    startActivity(intent);
}

B中接收A的数据:

@Override
public void initData() {
    mPhotoList = (ArrayList) MediaApplication.getInstance().getPhotoList();// 解决异常:JavaBinder: !!! FAILED BINDER TRANSACTION !!!
    currentPosition = getIntent().getIntExtra(Constants.PHOTO_CURRENT_POSITION, -1);
}

你可能感兴趣的:(Android)