ロード画像OOM問題まとめ
20397 ワード
画像oom問題のロード
1、OOMが現れるシーンと原因
シーンは次のとおりです.
主な原因:
2、どのように大きい図のロードの問題を解決します
実際に画像をロードするときは、元の大きな図をロードすることはめったにありません.一般的には、スケールでサンプリングしてスケールします.これにより、メモリを節約し、画像が歪まないことを保証します.具体的な実施手順は以下の通りである.
(1)、ピクチャの内容をロードしない上で、ピクチャを復号してピクチャのサイズ情報を得る
ここで必要なBitmapFactoryのdecodeシリーズメソッドとBitmapFactory.Options.decodeシリーズメソッドを使用してピクチャをロードする場合は、OptionsのinJustDecodeBoundsプロパティをtrueに設定する必要があります.
(2)、取得したピクチャのサイズと、インタフェースに表示するサイズからスケーリングを計算する
(3)、計算されたスケールに基づいて画像を拡大・縮小する
3、大量ロード大図
まず、インタフェースに表示される画像コントロールのサイズに基づいてスケールを決定します.
LruCacheを使用してピクチャをキャッシュするので、メモリオーバーフローの心配はありません.LruCacheに格納されているピクチャの合計サイズが容量上限に達すると、最近最も少ないピクチャが自動的にキャッシュから削除されます.
転載先:https://www.cnblogs.com/zxpy/p/10563744.html
1、OOMが現れるシーンと原因
シーンは次のとおりです.
1、
2、
3、
主な原因:
1、 APP , 16M, , , 。
2、 Android , Android2.3 ARGB_8888, 4 。 。
2、どのように大きい図のロードの問題を解決します
実際に画像をロードするときは、元の大きな図をロードすることはめったにありません.一般的には、スケールでサンプリングしてスケールします.これにより、メモリを節約し、画像が歪まないことを保証します.具体的な実施手順は以下の通りである.
(1)、ピクチャの内容をロードしない上で、ピクチャを復号してピクチャのサイズ情報を得る
ここで必要なBitmapFactoryのdecodeシリーズメソッドとBitmapFactory.Options.decodeシリーズメソッドを使用してピクチャをロードする場合は、OptionsのinJustDecodeBoundsプロパティをtrueに設定する必要があります.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds=true;
BitmapFactory.decodeFile(path, options);
(2)、取得したピクチャのサイズと、インタフェースに表示するサイズからスケーリングを計算する
public int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
}
return inSampleSize;
}
(3)、計算されたスケールに基づいて画像を拡大・縮小する
//
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
Bitmap bitmap= BitmapFactory.decodeFile(path, options);
3、大量ロード大図
まず、インタフェースに表示される画像コントロールのサイズに基づいてスケールを決定します.
public class PhotoWallAdapter extends ArrayAdapter implements OnScrollListener {
/**
* 。
*/
private Set taskCollection;
/**
* , , 。
*/
private LruCache mMemoryCache;
/**
* GridView
*/
private GridView mPhotoWall;
/**
*
*/
private int mFirstVisibleItem;
/**
*
*/
private int mVisibleItemCount;
/**
* , , 。
*/
private boolean isFirstEnter = true;
public PhotoWallAdapter(Context context, int textViewResourceId, String[] objects,
GridView photoWall) {
super(context, textViewResourceId, objects);
mPhotoWall = photoWall;
taskCollection = new HashSet();
//
int maxMemory = (int) Runtime.getRuntime().maxMemory();
int cacheSize = maxMemory / 8;
// 1/8
mMemoryCache = new LruCache(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getByteCount();
}
};
mPhotoWall.setOnScrollListener(this);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final String url = getItem(position);
View view;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(R.layout.photo_layout, null);
} else {
view = convertView;
}
final ImageView photo = (ImageView) view.findViewById(R.id.photo);
// ImageView Tag,
photo.setTag(url);
setImageView(url, photo);
return view;
}
/**
* ImageView 。 LruCache , ImageView 。 LruCache ,
* ImageView 。
*
* @param imageUrl
* URL , LruCache 。
* @param imageView
* 。
*/
private void setImageView(String imageUrl, ImageView imageView) {
Bitmap bitmap = getBitmapFromMemoryCache(imageUrl);
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
imageView.setImageResource(R.drawable.empty_photo);
}
}
/**
* LruCache 。
*
* @param key
* LruCache , URL 。
* @param bitmap
* LruCache , Bitmap 。
*/
public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemoryCache(key) == null) {
mMemoryCache.put(key, bitmap);
}
}
/**
* LruCache , null。
*
* @param key
* LruCache , URL 。
* @return Bitmap , null。
*/
public Bitmap getBitmapFromMemoryCache(String key) {
return mMemoryCache.get(key);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// GridView ,GridView
if (scrollState == SCROLL_STATE_IDLE) {
loadBitmaps(mFirstVisibleItem, mVisibleItemCount);
} else {
cancelAllTasks();
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
mFirstVisibleItem = firstVisibleItem;
mVisibleItemCount = visibleItemCount;
// onScrollStateChanged , onScrollStateChanged ,
// 。
if (isFirstEnter && visibleItemCount > 0) {
loadBitmaps(firstVisibleItem, visibleItemCount);
isFirstEnter = false;
}
}
/**
* Bitmap 。 LruCache ImageView Bitmap ,
* ImageView Bitmap , 。
*
* @param firstVisibleItem
* ImageView
* @param visibleItemCount
*
*/
private void loadBitmaps(int firstVisibleItem, int visibleItemCount) {
try {
for (int i = firstVisibleItem; i < firstVisibleItem + visibleItemCount; i++) {
String imageUrl = Images.imageThumbUrls[i];
Bitmap bitmap = getBitmapFromMemoryCache(imageUrl);
if (bitmap == null) {
BitmapWorkerTask task = new BitmapWorkerTask();
taskCollection.add(task);
task.execute(imageUrl);
} else {
ImageView imageView = (ImageView) mPhotoWall.findViewWithTag(imageUrl);
if (imageView != null && bitmap != null) {
imageView.setImageBitmap(bitmap);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 。
*/
public void cancelAllTasks() {
if (taskCollection != null) {
for (BitmapWorkerTask task : taskCollection) {
task.cancel(false);
}
}
}
/**
* 。
*
* @author guolin
*/
class BitmapWorkerTask extends AsyncTask {
/**
* URL
*/
private String imageUrl;
@Override
protected Bitmap doInBackground(String... params) {
imageUrl = params[0];
//
Bitmap bitmap = downloadBitmap(params[0]);
if (bitmap != null) {
// LrcCache
addBitmapToMemoryCache(params[0], bitmap);
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
// Tag ImageView , 。
ImageView imageView = (ImageView) mPhotoWall.findViewWithTag(imageUrl);
if (imageView != null && bitmap != null) {
imageView.setImageBitmap(bitmap);
}
taskCollection.remove(this);
}
/**
* HTTP , Bitmap 。
*
* @param imageUrl
* URL
* @return Bitmap
*/
private Bitmap downloadBitmap(String imageUrl) {
Bitmap bitmap = null;
HttpURLConnection con = null;
try {
URL url = new URL(imageUrl);
con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(5 * 1000);
con.setReadTimeout(10 * 1000);
bitmap = BitmapFactory.decodeStream(con.getInputStream());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (con != null) {
con.disconnect();
}
}
return bitmap;
}
}
}
LruCacheを使用してピクチャをキャッシュするので、メモリオーバーフローの心配はありません.LruCacheに格納されているピクチャの合計サイズが容量上限に達すると、最近最も少ないピクチャが自動的にキャッシュから削除されます.
転載先:https://www.cnblogs.com/zxpy/p/10563744.html