在Cordova Project中的Android 4.1上,将二进制图像数据加载到图像失败

时间:2015-06-08 14:50:25

标签: android cordova sencha-touch blob filereader

我在将二进制图像数据加载到简单的图像元素时遇到了严重问题。我编写了一个cordova应用程序(使用Sencha touch),它按以下方式加载图像:

xhr.open('GET', imageUrl, true);
xhr.responseType = 'blob';

xhr.addEventListener('load', function () {
    if (xhr.status === 200) {
        // onload needed since Google Chrome doesn't support addEventListener for FileReader
        fileReader.onload = function (evt) {
            image.setSrc(evt.target.result);
        };
        // Load blob as Data URL
        fileReader.readAsDataURL(xhr.response);
    }
}, false);

在Android 5和4.4(这些是我测试过的)上,它就像一个魅力。现在我在华硕平板电脑上运行Android 4.1并且onload回调不会被解雇。当我在readAsDataURL函数中抛出一个blob时,至少触发了onload回调,但图像也没有显示任何图像:(

有没有人提出建议,失败可能是什么,或者我做错了什么?

1 个答案:

答案 0 :(得分:1)

啊,最后我用以下代码在Android 4.1.1(华硕平板电脑)上工作了。另一个问题是,从xhr中保存arraybuffer响应不能简单地序列化,所以我将这些东西转换为字符串。另外我考虑到blob,在某些系统上,Blob对象根本就不存在:

function arrayBufferToString(buf) {
    return String.fromCharCode.apply(null, new Uint8Array(buf));
};

function stringToArrayBuffer(str) {
    var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char
    var bufView = new Uint8Array(buf);
    for (var i=0, strLen=str.length; i<strLen; i++) {
        bufView[i] = str.charCodeAt(i);
    }
    return buf;
};

function getBlob(content, type) {
    var blob = null;

    // Android 4 only has the deprecated BlobBuilder :-(
    try {
        blob = new Blob([content], {type: type});
    } catch(e) {
        window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||
        window.MozBlobBuilder || window.MSBlobBuilder;

        if (window.BlobBuilder)
        {
            var bb = new BlobBuilder();
            bb.append(content);
            blob = bb.getBlob(type);
        }
    }

    return blob;
};

cachedFile = getCachedFile(...); // not of interest here, I think :-)
if (cachedFile)
{
    callback.apply(this, [window.webkitURL.createObjectURL(getBlob(stringToArrayBuffer(cachedFile.data), 'image/jpeg'))]);
}
else {
    xhr.open('GET', imageUrl, true);
    xhr.responseType = 'arraybuffer';

    xhr.addEventListener('load', function () {
        if (xhr.status === 200) {
            cachedFile = {
                url: imageUrl,
                data: arrayBufferToString(xhr.response)
            };

            addCachedFile(cachedFile); // not of interest here, I think :-)

            callback.apply(this, [window.webkitURL.createObjectURL(getBlob(xhr.response, 'image/jpeg'))]);
        }
    }, false);
    // Send XHR
    xhr.send();
}

编辑:刚做了一点改动,现在使用了Uint8Array Class而不是Uint16Array Class,因为我遇到了错误:&#34; RangeError:Uint16Array的字节长度应该是2的倍数&# 34 ;.现在效果很好。

Edit2:刚才看到,由于使用了Uint8Array,上述代码在所有情况下都无法解决。 Uint16Array。

现在我认为我有一个可靠的解决方案:我使用带有此处http://appcropolis.com/blog/web-technology/javascript-encode-images-dataurl/功能的画布将图像url响应的二进制文件转换为base64。花一点时间,但仍然是一个有效的解决方案:)