Android中显示PNG图标背景变黑色


        最近项目中遇到一个问题:就是从网络获取应用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格式了~~