Tag Archives: Bitmap is too large

Javabinder:

JavaBinder: !!! FAILED BINDER TRANSACTION !!! Solution analysis for exceptions

is the cause of

I have been in charge of the development of the company’s mobile multimedia app. Recently, I was in charge of A project: in an Activity, I read the picture files in the external usb disk and encapsulated them as

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;

    ......
}

and display thumbnails in a list, when you click on the display image, pass all the data to B (dedicated to display the image) :

AActivity.java:
private void enterBActivity(ArrayList<MediaFileBean> 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 receives data from A:

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

but if the usb disk contains a lot of pictures, no matter how point, is not into the B page, the program does not crash, background print logcat, found JavaBinder:!!! FAILED BINDER TRANSACTION !!! Error

cause of occurrence

online search, the general reason is that the Bitmap should not be more than 40KB for data delivery with intents. According to the official website, data delivery with intents is limited, the maximum size is about 1M

solution

1. Try not to pass the Bitmap in intents. saves the bitmap to be passed in the SD, instead of the url in the Intent.

2. If you really want to pass the Bitmap, to its compression

`/**
 * 压缩图片
 * 该方法引用自: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. data to be passed to the global variable

is not helpful if you have a large amount to pass. In my example above, even if I remove the bitmap variable from the bean, I still get an error because the array I’m passing is too large! Another way to think about it is that the data to be passed will be placed in a fixed value in the life cycle and assigned to value at any time. When you think about it, it is appropriate to put it in the Application:

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

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

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

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

}

when A jumps to B:

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

B received A data:

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