EL 1.2中新增了词典功能, 急着release, 就没有在2.3.x下测试 (当然了, 我的G7被我刷成4.2.2之后, 也没有2.3.x的环境了..), 编译没有问题, 4.x上都OK, 然后就release了... 唉, 债总是要连本带利地归还的, 现实如此, 敲字亦是如此啊...因此这个周末, 整个周末都在修改EL无法在android 2.3.x上运行的问题.
知道Android有版本碎化问题, 只是没想到这么'细节', 不碰到那真是根本想不到啊...还是前年做IOS好, 就没考虑版本问题,当然也可能没碰到. 不吐槽了, 敲字的人嘛, 抱怨不能解决问题啊, 还得靠review/debug...
这次发现了两处不兼容的地方, 一个是java语言层面的, 另外一个则是android控件相关的.
1. ByteBuffer
EL在从Lingoes词典文件中提取数据时, 需要使用InflaterInputStream对象解压原始数据, 代码如下:
private static int decompressBlock(ByteBuffer in, int size, byte[] out) {
final Inflater inflater = new Inflater();
byte[] a = null;
if (in.hasArray()) {
a = in.array();
} else {
a = new byte[size];
in.position(0);
in.get(a, 0, size);
}
final InflaterInputStream stream = new InflaterInputStream(new ByteArrayInputStream(a, 0, size), inflater, size);
try {
while(stream.read(out) > 0);
} catch (IOException e) {
return -1;
}
inflater.end();
return 0;
}
此对象的一个传入参数为InputStream, 这样正好将ByteButter对象数组化为byte[]后, 构造出一个ByteArrayInputStream实例传入. 那么ByteBuffer常用且推荐的方式就是直接调用其array()方法, 这样就无需在申请和构造个新的byte[]空间了.
问题就在这里, 在android 2.3.x中, ByteBuffer对象是不支持直接数组化的, 在调用arry()时, 会抛出NotSupportedException异常的. 因此为了保持兼容就需要在数组化前使用hasArray()方法检查是否可以数组化, 如果不能, 那就要重新申请数组空间了.
2. PopupMenu
EL在播放时, 支持快速跳转到ESL课程的指定位置上. 如下图所示.


指定位置的选择菜单是通过PopupMenu实现的, 但这个控件是在API 11才有的, 意味着低于HONEYCOMB版本的2.3.x平台是没法使用的. 实际这个问题可以早点发现的, 但我就是懒了, 以后relase前, 还是需要运行下Android Lint的.
上图可以看出在两种平台下, 这个'PopupMenu'是不一样的, 那是因为2.3.x平台上, 我是用PopupWindow控件模拟了类似PopupMenu的功能. 以后有时间看看能不能搞的UI也一样就好了.
这种控件上的不兼容, 可以使用不同平台下运行不同代码来解决.
private void showPopupMenu(View v) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
PopupMenu pm = new PopupMenu(getELActivity(), v);
pm.getMenuInflater().inflate(R.menu.fragment_show_pop, pm.getMenu());
pm.getMenu().getItem(0).setEnabled(audioSlowDialog != -1);
pm.getMenu().getItem(1).setEnabled(audioExplanation != -1);
pm.getMenu().getItem(2).setEnabled(audioFastDialog != -1);
pm.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return onNavigate(item.getItemId());
}
});
pm.show();
} else {
final ShowPopWindow win = new ShowPopWindow(getELActivity(), v);
win.setItemEnable(0, (audioSlowDialog != -1));
win.setItemEnable(1, (audioExplanation != -1));
win.setItemEnable(2, (audioFastDialog != -1));
win.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onNavigate(v.getId());
win.dismiss();
}
});
win.show();
}
}
本来想着更新下修改好的EL版本赶紧release了, 毕竟2.3.x还占有30%左右的份额, 是不能放弃的部分. 但还是有些心虚, 所以啊, 再检查下, 明天再说吧..(整个周末都在fix兼容问题, 头昏眼花啊, 睡觉去了...唉, 毕竟java没有C++玩的那么久, 很多基本的语言级别的问题都不清楚, 还要多敲敲才行啊..)