最近项目中遇到一个问题:就是从网络获取应用PNG图标后,显示到GridView中,发现图标透明的地方都变成了黑色?为什么呢?
个人习惯有问题先梳理一遍代码:
一、从网络异步下载图标并显示代码
class IconAsyncTask extends AsyncTask {
private AdsInfo tAdsInfo;
private ImageView tAppIcon;
public IconAsyncTask(ImageView appIcon, AdsInfo adsInfo) {
// TODO Auto-generated constructor stub
tAppIcon = appIcon;
tAdsInfo = adsInfo;
}
@Override
protected Bitmap doInBackground(String... params) {
// TODO Auto-generated method stub
Bitmap icon = getBitmapFromURL(params[0]);
try {
FileUtil.writeImgFile(icon, getIconPath(tAdsInfo.id));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return icon;
}
@Override
protected void onPostExecute(Bitmap result) {
// TODO Auto-generated method stub
if (tAppIcon.getTag().equals(tAdsInfo.url)) {
tAppIcon.setImageBitmap(result);
}
}
}
其中,getBitmapFromURL()为从网络获取bitmap, writeImgFile()为保存图片到本地,具体代码看后面~
二、从网络获取Bitmap具体代码
private Bitmap getBitmapFromURL(String urlString) {
Bitmap bitmap = null;
InputStream is = null;
HttpURLConnection connection = null;
for (int i = 0; i < Constants.NETWORK_RETRY_NUM; i++) {
try {
URL url = new URL(urlString);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.setDoInput(true);
connection.setDoOutput(false);
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
is = new BufferedInputStream(connection.getInputStream());
bitmap = BitmapFactory.decodeStream(is);
break;
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (connection != null) {
connection.disconnect();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return bitmap;
}
三、将Bitmap以PNG格式保存到本地
public static void writeImgFile(Bitmap bitmap, String fileName)
throws IOException {
writeImgFile(bitmap, Bitmap.CompressFormat.PNG, new File(fileName));
}
public static void writeImgFile(Bitmap bitmap, CompressFormat format,
File file) throws IOException {
File parentDir = file.getParentFile();
if ((parentDir != null) && !parentDir.exists()) {
parentDir.mkdirs();
}
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(file));
bitmap.compress(format, 100, bos);
bos.flush();
bos.close();
}
四、保存路径代码
private String getIconPath(int id) {
String iconPath = StringUtil.stringAppend(
SettingUtil.getDownloadPath(mContext), File.separator,
Constants.BannerInfo.bannericon.info, File.separator,
String.valueOf(id));
return iconPath;
}
五、分析解决问题
代码走了一遍,没发现有问题,再用Android工具Hierarchy Viewer查看,发现图片的背景本身就是黑色的,说明什么呢?只有两种原因:一保存的图片为非PNG格式,二读取图片出错。
再看代码,上面保存图片语句:writeImgFile(bitmap, Bitmap.CompressFormat.PNG, new File(fileName));确定保存为PNG格式。
那读取显示图片呢?只是读取bitmap图片并显示,并不知道具体显示的是什么格式图片。难道真是这个问题? 于是把保存路径后面加上后缀名“.png”, 代码如下
private String getIconPath(int id) {
String iconPath = StringUtil.stringAppend(
SettingUtil.getDownloadPath(mContext), File.separator,
Constants.BannerInfo.bannericon.info, File.separator,
String.valueOf(id), ".png");
return iconPath;
}
再运行,果然,PNG完美显示。
看来保存PNG格式图片时要注意加上后缀,否则在读取时有可能变成JPG格式了~~