PhoneGap是很棒的一个跨平台移动开发解决方案。该方案提供了一系列主流平台的底层封装,使得我们可以使用简单的HTML5 + javascript开展跨平台的移动应用开发,从而重用了我们传统应用开发的技能。
目前该团队已经被Adobe收购,并贡献给了Apache,重新命名为Apache Callback(这烂名字怎么来的,怎么就让人感觉不到其价值呢)。目前还在孵化器。
Apache链接:http://incubator.apache.org/projects/callback.html
Github:https://github.com/callback/
在初步的使用过程中发现一个比较严重的问题,是这样的。
我们加载图片经常使用的Android SDK API是:BitmapFactory.decodeStream。
其思路是先decode为bitmap然后简单设置ImageView的src即可,简单方便。
然而大家也都知道,现在的摄像机像素,简直是朝着存储不要钱,逼真不要命的方向发展,其图片小则几m大则几十m。
问题就这样来了,decodeSteam的时候,动不动就会抛出OutOfMemory的异常,然后force close。
怎么解决呢,查了一些资料,最终得到近乎完美的解决。
首先我们要明确我们输出的宽度或高度。如果我们不进行合理的缩放,倔强地要一股脑儿加载到JVM(哦,GOOGLE不喜欢这名字,改名叫Dalvik VM)的话,没辙,还是必死无疑,毕竟房子就这么大,非要挤进去,爆棚是必须的了。所以指定合理的高度或者宽度,是必须的——其实几十m的图片挤在一个几英寸的屏幕,压根也不会显得更好看些。
然后要进行合理sacle比例的计算,确定接近大小的scaled图片。
最后再encodeStream,转换为Bitmap。
当然了,如果要resize的更精准,也是可以的,这一步可选了。
下面是safeDecodeStream,用以替代默认的BitmapFactory.decodeStream。
/**
* A safer decodeStream method
* rather than the one of {@link BitmapFactory}
* which will be easy to get OutOfMemory Exception
* while loading a big image file.
*
* @param uri
* @param width
* @param height
* @return
* @throws FileNotFoundException
*/
protected Bitmap safeDecodeStream(Uri uri, int width, int height)
throws FileNotFoundException{
int scale = 1;
BitmapFactory.Options options = new BitmapFactory.Options();
android.content.ContentResolver resolver = this.ctx.getContentResolver();
if(width>0 || height>0){
// Decode image size without loading all data into memory
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(
new BufferedInputStream(resolver.openInputStream(uri), 16*1024),
null,
options);
int w = options.outWidth;
int h = options.outHeight;
while (true) {
if ((width>0 && w/2 < width)
|| (height>0 && h/2 < height)){
break;
}
w /= 2;
h /= 2;
scale *= 2;
}
}
// Decode with inSampleSize option
options.inJustDecodeBounds = false;
options.inSampleSize = scale;
return BitmapFactory.decodeStream(
new BufferedInputStream(resolver.openInputStream(uri), 16*1024),
null,
options);
}
对了,我提了一个enhancement给Apache Callback.
链接:https://issues.apache.org/jira/browse/CB-14
需要指出的是,这里的参数Uri如果你觉得不方面,完成可以提供系列可选参数,比如
1. String fileName - 指定文件路径
2. URL
3. InputStream
4. etc.
仅供参考。谢谢!