在安卓中获取网络图片通常使用第三方库(如Glide、Picasso)或手动通过OkHttp
、Retrofit
下载,以下以手动下载为例:
// 使用OkHttp下载图片 OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url("https://example.com/image.jpg").build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { // 处理失败 } @Override public void onResponse(Call call, Response response) throws IOException { InputStream inputStream = response.body().byteStream(); Bitmap bitmap = BitmapFactory.decodeStream(inputStream); // 后续压缩处理 } });
通过BitmapFactory.Options
的inSampleSize
参数减少内存占用:
public static Bitmap decodeSampledBitmap(InputStream is, int reqWidth, int reqHeight) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(is, null, options); // 计算采样率 options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); options.inJustDecodeBounds = false; return BitmapFactory.decodeStream(is, null, options); } private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfHeight = height / 2; final int halfWidth = width / 2; while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) { inSampleSize = 2; } } return inSampleSize; }
通过Bitmap.compress()
方法调整JPEG质量:
public static byte[] compressBitmap(Bitmap bitmap, int quality) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos); return baos.toByteArray(); }
// 异步任务处理压缩 class CompressTask extends AsyncTask<InputStream, Void, byte[]> { @Override protected byte[] doInBackground(InputStream... inputs) { try { // 1. 尺寸压缩 Bitmap bitmap = decodeSampledBitmap(inputs[0], 800, 600); // 2. 质量压缩 return compressBitmap(bitmap, 80); // 质量参数范围:0-100 } catch (Exception e) { e.printStackTrace(); return null; } } @Override protected void onPostExecute(byte[] result) { // 保存或上传压缩后的图片 } }
优化方式 | 说明 |
---|---|
inSampleSize |
通过采样率降低Bitmap内存占用 |
Bitmap.recycle() |
手动回收不再使用的Bitmap对象 |
LruCache |
使用缓存避免重复解码 |
WebP格式 |
采用更高效的图片编码格式 |
问题 | 解决方案 |
---|---|
OOM错误 | 使用inSampleSize 分区域加载( BitmapRegionDecoder )启用大内存模式(Android 11+) |
压缩后模糊 | 适当提高quality 参数优先保证尺寸压缩比例合理 |
性能瓶颈 | 使用Glide/Picasso 代替手动处理开启多线程压缩 |
A:可结合DiskLruCache
或第三方库(如Glide)实现持久化缓存:
// 使用Glide缓存(自动处理内存和磁盘缓存) Glide.with(context) .load("https://example.com/image.jpg") .override(800, 600) // 尺寸限制 .diskCacheStrategy(DiskCacheStrategy.ALL) // 强制缓存 .into(imageView);
A:动态图片需特殊处理:
Glide
的asGif()
方法)