Amazon Kindle Fire中的java.lang.OutOfMemoryError

时间:2014-01-30 04:42:57

标签: android memory bitmap

我知道很多关于这个的问题已经发布在堆栈溢出中。实际上我已经完成了并实现了一些方法。但仍然没有运气,它仍然显示与之前相同的错误。这是我的代码。

public class ViewPagerAdapter extends PagerAdapter {

Activity activity;
int imageArray[];
LayoutInflater inflater;
Typeface tf;
ImageView imageView;
ArrayList<Bitmap> list=new ArrayList<Bitmap>();;
Bitmap bitmap;
public ViewPagerAdapter(Activity act, int[] imgArra) {
    imageArray = imgArra;
    activity = act;
    inflater = (LayoutInflater) act
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    tf = Typeface.createFromAsset(activity.getAssets(), "Times Roman.ttf");
}

public int getCount() {
    return imageArray.length;
}

public Object instantiateItem(View collection, int position) {
    // System.out.println("instantiate.... " + position);
    // ImageView view = new ImageView(activity);
    // view.setBackgroundColor(Color.parseColor("#909090"));
    // view.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
    // LayoutParams.FILL_PARENT));
    // view.setImageResource(imageArray[position]);
    // ((ViewPager) collection).addView(view, 0);
    // return view;
    try {

        View view;

        view = inflater.inflate(R.layout.item_starting_screen, null);
        TextView textView = (TextView) view
                .findViewById(R.id.txt_heading_starting_screen);
        textView.setText(activity.getResources().getStringArray(
                R.array.txt_starting_screen)[position]);
        textView.setTypeface(tf, Typeface.BOLD_ITALIC);
        imageView=(ImageView) view.findViewById(R.id.img_starting_screen);
                      imageView.setImageBitmap(BitmapFactory.decodeResource(activity.getResources(), imageArray[position]));
        bitmap=((BitmapDrawable)imageView.getDrawable()).getBitmap();
        list.add(bitmap);
        ((ViewPager) collection).addView(view, 0);
        return view;
    } catch (Exception e) {
        // TODO: handle exception
        e.printStackTrace();
        return null;
    }

}

@Override
public void destroyItem(View arg0, int arg1, Object arg2) {

    ((ViewPager) arg0).removeView((View) arg2);


}

@Override
public boolean isViewFromObject(View arg0, Object arg1) {
    return arg0 == ((View) arg1);
}

@Override
public Parcelable saveState() {
    return null;
}
public void clearbitmap(int flag)
{
    if(flag==1)
    {
        for(int i=0;i<list.size();i++)
        {
            bitmap=list.get(i);
            bitmap.recycle();
        }


    }
}

}

经过大量搜索,我想出了回收方法,但仍然无法正常工作。 当我第一次运行我的应用程序时没有问题。第二次它会崩溃。

我有5个页面,如应用程序的介绍,当用户完成应用程序启动时。启动时我设置一个标志并调用名为clearbitmap的方法并使用recycle方法清除位图。

我已经缩小了我的图像尺寸,但仍然没有工作。但是当我使用小分辨率图像时,它可以工作。但我不想那样。我使用的是亚马逊Kindle Fire作为我的测试设备。这个问题只是使用此设备。其余的设备工作正常。

我按照rajahsekar给出的链接,我改变了我的代码,但仍然崩溃了

     BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(activity.getResources(),      imageArray[position], options);
         int imageHeight = options.outHeight;
        int imageWidth = options.outWidth;
                                 imageView.setImageBitmap(decodeSampledBitmapFromResource(activity.getResources(),imageArray[ position],imageWidth,imageHeight));

使用此方法计算位图

  public static 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) {

    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 static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

但仍然没有运气。

2 个答案:

答案 0 :(得分:1)

一条建议,虽然可能没有回答

public void clearbitmap(int flag)
{
    if(flag==1)
    {
        for(int i=0;i<list.size();i++)
        {
            bitmap=list.get(i);
            bitmap.recycle();
        }


    }
}

代替

public void clearbitmap(int flag)
{
    if(flag==1)
    {
        list.removeAll();

    }
}

更重要的是。

只有在您希望以索引方式访问时才应使用ArrayList。在任何其他情况下使用LinkedList。在ArrayList中,删除Item是O(n)时间和严重惩罚,其中作为LinkedList,删除项目是O(1)。

由于删除了一个项目,因此在ArrayList中,所有后续项目都将通过复制元素被索引撞击。我不会详细解释,但您可以通过查看收藏维基

来查看

答案 1 :(得分:0)

压缩位图并将其保存在缓存中。请查看以下链接http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

从列表中删除所有位图。