所以我的活动是高清图像的网格视图,缩小到大约64x64像素的盒子。我希望能够获取图像,然后将它们加载到活动中,但是我收到一条错误消息,指出加载所有图片所需的内存比模拟器/手机可以处理的要高很多。
我通过进入photoshop和制作64x64图像解决了这个问题,但我看到了运行视频的应用程序,并且在当前活动的视图中有数百个图像。他们如何使用一个列表视图中的所有内存进行编译?
我有另一个应用程序,它是一个播放带有20张图片的全屏动画的动画 - 但它在Android Studio中具有相同的内存绑定错误。
如何在单个活动中加载20张图片而不会出现内存不足错误。
使用GridView的活动代码 @覆盖 protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); 的setContentView(R.layout.wallpapers);
//**
//Gridview, onclick of icon will open up dialog
//allows to SAVE, SET, CANCEL - not in that order
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Toast.makeText(Wallpaper.this, "Setting BG to ..." + position,
Toast.LENGTH_SHORT).show();
}
});
}
ImageAdapter代码
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
// references to our images
private Integer[] mThumbIds = {
R.raw.es_1_pix, R.raw.es1_c, R.raw.es2_c, R.raw.es_1_pix
//.raw.es_1_pix,R.raw.es_1_pix,R.raw.es_1_pix,R.raw.es_1_pix,R.raw.es_1_pix
//R.raw.es2_c, R.raw.es3_c, R.raw.es4_c,
//R.raw.es5_c, R.raw.es6_c, R.raw.es7_c
};
}
答案 0 :(得分:3)
不确定声音,但我知道图片需要使用inJustDecodeBounds=true
的样本尺寸。
public int calculateInSampleSize(BitmapFactory.Options options) {
DisplayMetrics displayMetrics = cxt.getResources().getDisplayMetrics();
int reqWidth = displayMetrics.widthPixels;
final int height = options.outHeight;
final int width = options.outWidth;
double devCal2 = (height*1000)/width;
int reqHeight = (int) ((devCal2/1000)*reqWidth);
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public Bitmap createBitmap(){
BitmapFactory.Options options2 = new BitmapFactory.Options();
options2.inJustDecodeBounds = true;
options2.inDither=true;
BitmapFactory.decodeFile(cxt.getExternalFilesDir(filepath) +"/companylogo.png",options2);
options2.inSampleSize = calculateInSampleSize(options2);//=32
options2.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(cxt.getExternalFilesDir(filepath) +"/companylogo.png",options2);
}
如需参考,请查看http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
答案 1 :(得分:1)
有几件事需要考虑。
在任何地方使用WeakReference<Bitmap>
而不是位图。 WeakReference意味着当内存不足时,System可以从内存中清除图像。
如果显示20个64 * 64图像,而不是确保不在内存中存储20个1024 * 1024图像,请在运行时或应用程序外部将其大小调整为64 * 64。
一般来说,android可以轻松处理20个平均大小的图像(显然不是很大的图像)。如果它发生了冲突,那么代码就会出现问题。
代码发布后更新:资源文件中的图像很大,缩小,你应该没问题。
答案 2 :(得分:0)
如果你真的需要全高清图像,你可以计算出你需要多少空间,并将它们逐个加载到视图中,用占位符图像替换其他视图。然后在加载一个图像后,确保系统从内存中清除该图像。但是,就像大多数人都说的那样,如果只有20张图像崩溃,那可能就是别的了。