库活动中的outOfMemoryError

时间:2012-03-01 10:01:59

标签: android out-of-memory android-gallery

代码被注释用于解释,基本上我用下载的图像填充图库,但是当下载完成时,活动继续思考,直到outOfMemoryErrors在20秒后出现。我的图片永远不会显示:

public class PhotoDetailsActivity extends Activity {

    private MultimediaJson.PhotoCategory photoCategory;
    private int position;
    private Gallery gallery;
    private ImageManager im;
    private ArrayList<PhotoData> photos;
    private ArrayList<ImageView> ivArray;

    private LayoutInflater inflater;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.photo_detail_layout);

        inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);


        im = new Utils().new ImageManager();

        //I get the Images i've got to display from my intent
        photoCategory = (PhotoCategory) getIntent().getSerializableExtra(
                "photoDetails");
        //position is the image i've got to put the focus on
        position = (int) getIntent().getIntExtra("position", 1);

        //photoData is an arrayList of photo objects (containing the link)
        photos = photoCategory.photoData;


        ivArray = new ArrayList<ImageView>();
        gallery = (Gallery) findViewById(R.id.photoDetailGallery);

        //photo_detail_list_view_item is for the moment just an ImageView matching parent
        final PhotoAdapter pa = new PhotoAdapter(this,
                R.layout.photo_detail_list_view_item, ivArray);

        gallery.setAdapter(pa);

        //here is my downloading thread
        new Thread(new Runnable() {

            @Override
            public void run() {
                // for tests, will be pos<photos.size()
                for (int pos = 0; pos < 2; pos++) {
                    final ImageView imageView = new ImageView(getBaseContext());
                    imageView.setImageBitmap(im.downloadFromUrl(
                            photos.get(pos).photo.link,
                            photos.get(pos).photo.md5));
                    ivArray.add(imageView);

                    //adding the last photo to my adapter and notify it
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            if (ivArray != null && ivArray.size() > 0) {
                                pa.notifyDataSetChanged();
                                pa.add(ivArray.get(ivArray.size()-1));
                            }
                            pa.notifyDataSetChanged();
                        }
                    });

                }

            }
        }).start();

    }

我的适配器:

private class PhotoAdapter extends ArrayAdapter<ImageView> {

        ArrayList<ImageView> imageViews;

        public PhotoAdapter(Context context, int textViewResourceId,
                ArrayList<ImageView> images) {
            super(context, textViewResourceId, images);
            imageViews = images;
        }

        public boolean isEnabled(int position) {
            return false;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            if (convertView == null) {
                convertView = inflater.inflate(
                        R.layout.photo_detail_list_view_item, null);
            }
            final ImageView iv = imageViews.get(position);
            if (iv != null) {
                ImageView iv2 = (ImageView) convertView
                        .findViewById(R.id.photo_detail_list_view_image_view);
                iv2 = iv;
            }

            return convertView;
        }

    }

和我的日志猫:

03-01 10:44:20.343: I/renaud(8553): downloadFromUrl begin
03-01 10:44:20.343: I/renaud(8553): imageFileCreated
03-01 10:44:20.343: I/renaud(8553): imageFile do exists //my images are well download there
03-01 10:44:20.484: D/dalvikvm(8553): GC_EXTERNAL_ALLOC freed 74K, 40% free 5106K/8455K, external 4970K/5134K, paused 25ms
03-01 10:44:21.074: D/dalvikvm(8553): GC_CONCURRENT freed 1832K, 45% free 5290K/9607K, external 5830K/6207K, paused 2ms+3ms
03-01 10:44:21.472: D/dalvikvm(8553): GC_FOR_MALLOC freed 1699K, 44% free 5405K/9607K, external 4970K/6207K, paused 30ms
03-01 10:44:21.855: D/dalvikvm(8553): GC_FOR_MALLOC freed 1726K, 44% free 5578K/9799K, external 4970K/6207K, paused 32ms
03-01 10:44:21.855: I/dalvikvm-heap(8553): Grow heap (frag case) to 13.435MB for 794336-byte allocation
03-01 10:44:21.890: D/dalvikvm(8553): GC_FOR_MALLOC freed 517K, 46% free 5836K/10631K, external 4970K/6207K, paused 25ms
03-01 10:44:22.578: D/dalvikvm(8553): GC_CONCURRENT freed 2010K, 45% free 5899K/10631K, external 4970K/6207K, paused 2ms+8ms
03-01 10:44:22.601: D/dalvikvm(8553): GC_FOR_MALLOC freed 62K, 46% free 5836K/10631K, external 4970K/6207K, paused 26ms
03-01 10:44:22.605: I/dalvikvm-heap(8553): Grow heap (frag case) to 14.067MB for 1191496-byte allocation
03-01 10:44:22.644: D/dalvikvm(8553): GC_FOR_MALLOC freed 775K, 48% free 6224K/11847K, external 4970K/6207K, paused 27ms
03-01 10:44:23.249: D/dalvikvm(8553): GC_CONCURRENT freed 2034K, 48% free 6238K/11847K, external 4970K/6207K, paused 1ms+16ms
03-01 10:44:23.546: D/dalvikvm(8553): GC_FOR_MALLOC freed 1073K, 48% free 6224K/11847K, external 4970K/6207K, paused 35ms
03-01 10:44:23.546: I/dalvikvm-heap(8553): Grow heap (frag case) to 15.013MB for 1787236-byte allocation
03-01 10:44:23.589: D/dalvikvm(8553): GC_FOR_MALLOC freed 1163K, 51% free 6806K/13639K, external 4970K/6207K, paused 31ms
03-01 10:44:24.191: D/dalvikvm(8553): GC_CONCURRENT freed 2038K, 51% free 6816K/13639K, external 4970K/6207K, paused 2ms+14ms
03-01 10:44:24.773: D/dalvikvm(8553): GC_CONCURRENT freed 2057K, 51% free 6806K/13639K, external 4970K/6207K, paused 2ms+17ms
03-01 10:44:24.960: D/dalvikvm(8553): GC_FOR_MALLOC freed 566K, 51% free 6806K/13639K, external 4970K/6207K, paused 37ms
03-01 10:44:24.964: I/dalvikvm-heap(8553): Grow heap (frag case) to 16.434MB for 2680844-byte allocation
03-01 10:44:25.011: D/dalvikvm(8553): GC_FOR_MALLOC freed 1745K, 44% free 7678K/13639K, external 4970K/6207K, paused 37ms
03-01 10:44:25.152: D/dalvikvm(8553): GC_CONCURRENT freed 173K, 44% free 7732K/13639K, external 4970K/6207K, paused 2ms+20ms
03-01 10:44:25.742: D/dalvikvm(8553): GC_CONCURRENT freed 2101K, 44% free 7678K/13639K, external 4970K/6207K, paused 2ms+20ms
03-01 10:44:26.339: D/dalvikvm(8553): GC_CONCURRENT freed 2048K, 44% free 7678K/13639K, external 4970K/6207K, paused 2ms+22ms
03-01 10:44:26.945: D/dalvikvm(8553): GC_CONCURRENT freed 2048K, 44% free 7678K/13639K, external 4970K/6207K, paused 2ms+23ms
03-01 10:44:27.167: D/dalvikvm(8553): GC_FOR_MALLOC freed 623K, 44% free 7678K/13639K, external 4970K/6207K, paused 45ms
03-01 10:44:27.175: I/dalvikvm-heap(8553): Grow heap (frag case) to 18.564MB for 4021256-byte allocation
03-01 10:44:27.234: D/dalvikvm(8553): GC_FOR_MALLOC freed 2618K, 49% free 8987K/17607K, external 4970K/6207K, paused 47ms
03-01 10:44:27.406: D/dalvikvm(8553): GC_CONCURRENT freed 210K, 49% free 9020K/17607K, external 4970K/6207K, paused 1ms+28ms
03-01 10:44:28.019: D/dalvikvm(8553): GC_CONCURRENT freed 2080K, 49% free 8987K/17607K, external 4970K/6207K, paused 2ms+29ms
03-01 10:44:28.640: D/dalvikvm(8553): GC_CONCURRENT freed 2047K, 49% free 8987K/17607K, external 4970K/6207K, paused 2ms+30ms
03-01 10:44:29.261: D/dalvikvm(8553): GC_CONCURRENT freed 2048K, 49% free 8987K/17607K, external 4970K/6207K, paused 1ms+32ms
03-01 10:44:29.878: D/dalvikvm(8553): GC_CONCURRENT freed 2047K, 49% free 8987K/17607K, external 4970K/6207K, paused 2ms+33ms
03-01 10:44:30.503: D/dalvikvm(8553): GC_CONCURRENT freed 2048K, 49% free 8987K/17607K, external 4970K/6207K, paused 2ms+35ms
03-01 10:44:30.558: D/dalvikvm(8553): GC_FOR_MALLOC freed 5K, 49% free 8987K/17607K, external 4970K/6207K, paused 51ms
03-01 10:44:30.570: I/dalvikvm-heap(8553): Grow heap (frag case) to 21.760MB for 6031876-byte allocation
03-01 10:44:30.640: D/dalvikvm(8553): GC_FOR_MALLOC freed 3927K, 54% free 10951K/23559K, external 4970K/6207K, paused 59ms
03-01 10:44:30.839: D/dalvikvm(8553): GC_CONCURRENT freed 248K, 54% free 10975K/23559K, external 4970K/6207K, paused 2ms+45ms
03-01 10:44:31.511: D/dalvikvm(8553): GC_CONCURRENT freed 2072K, 54% free 10951K/23559K, external 4970K/6207K, paused 2ms+42ms
03-01 10:44:32.234: D/dalvikvm(8553): GC_CONCURRENT freed 2047K, 54% free 10951K/23559K, external 4970K/6207K, paused 2ms+43ms
03-01 10:44:32.933: D/dalvikvm(8553): GC_CONCURRENT freed 2047K, 54% free 10951K/23559K, external 4970K/6207K, paused 2ms+45ms
03-01 10:44:33.613: D/dalvikvm(8553): GC_CONCURRENT freed 2048K, 54% free 10951K/23559K, external 4970K/6207K, paused 2ms+45ms
03-01 10:44:34.261: D/dalvikvm(8553): GC_CONCURRENT freed 2047K, 54% free 10951K/23559K, external 4970K/6207K, paused 1ms+47ms
03-01 10:44:34.945: D/dalvikvm(8553): GC_CONCURRENT freed 2047K, 54% free 10951K/23559K, external 4970K/6207K, paused 2ms+48ms
03-01 10:44:35.636: D/dalvikvm(8553): GC_CONCURRENT freed 2047K, 54% free 10951K/23559K, external 4970K/6207K, paused 2ms+50ms
03-01 10:44:36.019: D/dalvikvm(8553): GC_FOR_MALLOC freed 1113K, 54% free 10951K/23559K, external 4970K/6207K, paused 85ms
03-01 10:44:36.019: I/dalvikvm-heap(8553): Forcing collection of SoftReferences for 9047804-byte allocation
03-01 10:44:36.089: D/dalvikvm(8553): GC_FOR_MALLOC freed <1K, 54% free 10951K/23559K, external 4970K/6207K, paused 69ms
03-01 10:44:36.089: E/dalvikvm-heap(8553): Out of memory on a 9047804-byte allocation.
03-01 10:44:36.089: I/dalvikvm(8553): "main" prio=5 tid=1 RUNNABLE
03-01 10:44:36.089: I/dalvikvm(8553):   | group="main" sCount=0 dsCount=0 obj=0x4001f188 self=0xce60
03-01 10:44:36.089: I/dalvikvm(8553):   | sysTid=8553 nice=0 sched=0/0 cgrp=default handle=-1345006528
03-01 10:44:36.089: I/dalvikvm(8553):   at java.util.ArrayList.add(ArrayList.java:~123)
03-01 10:44:36.089: I/dalvikvm(8553):   at android.widget.ArrayAdapter.add(ArrayAdapter.java:178)
03-01 10:44:36.089: I/dalvikvm(8553):   at com.blablabla.PhotoDetailsActivity$1$1.run(PhotoDetailsActivity.java:77)
03-01 10:44:36.089: I/dalvikvm(8553):   at android.os.Handler.handleCallback(Handler.java:587)
03-01 10:44:36.089: I/dalvikvm(8553):   at android.os.Handler.dispatchMessage(Handler.java:92)
03-01 10:44:36.089: I/dalvikvm(8553):   at android.os.Looper.loop(Looper.java:130)
03-01 10:44:36.089: I/dalvikvm(8553):   at android.app.ActivityThread.main(ActivityThread.java:3683)
03-01 10:44:36.089: I/dalvikvm(8553):   at java.lang.reflect.Method.invokeNative(Native Method)
03-01 10:44:36.089: I/dalvikvm(8553):   at java.lang.reflect.Method.invoke(Method.java:507)
03-01 10:44:36.089: I/dalvikvm(8553):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
03-01 10:44:36.089: I/dalvikvm(8553):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
03-01 10:44:36.089: I/dalvikvm(8553):   at dalvik.system.NativeStart.main(Native Method)
03-01 10:44:36.089: D/AndroidRuntime(8553): Shutting down VM
03-01 10:44:36.089: W/dalvikvm(8553): threadid=1: thread exiting with uncaught exception (group=0x40015560)
03-01 10:44:36.101: E/AndroidRuntime(8553): FATAL EXCEPTION: main
03-01 10:44:36.101: E/AndroidRuntime(8553): java.lang.OutOfMemoryError
03-01 10:44:36.101: E/AndroidRuntime(8553):     at java.util.ArrayList.add(ArrayList.java:123)
03-01 10:44:36.101: E/AndroidRuntime(8553):     at android.widget.ArrayAdapter.add(ArrayAdapter.java:178)
03-01 10:44:36.101: E/AndroidRuntime(8553):     at com.blablabla.PhotoDetailsActivity$1$1.run(PhotoDetailsActivity.java:77)
03-01 10:44:36.101: E/AndroidRuntime(8553):     at android.os.Handler.handleCallback(Handler.java:587)
03-01 10:44:36.101: E/AndroidRuntime(8553):     at android.os.Handler.dispatchMessage(Handler.java:92)
03-01 10:44:36.101: E/AndroidRuntime(8553):     at android.os.Looper.loop(Looper.java:130)
03-01 10:44:36.101: E/AndroidRuntime(8553):     at android.app.ActivityThread.main(ActivityThread.java:3683)
03-01 10:44:36.101: E/AndroidRuntime(8553):     at java.lang.reflect.Method.invokeNative(Native Method)
03-01 10:44:36.101: E/AndroidRuntime(8553):     at java.lang.reflect.Method.invoke(Method.java:507)
03-01 10:44:36.101: E/AndroidRuntime(8553):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
03-01 10:44:36.101: E/AndroidRuntime(8553):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
03-01 10:44:36.101: E/AndroidRuntime(8553):     at dalvik.system.NativeStart.main(Native Method)

这是我的新ImageManager:

    public class ImageManager {

    public Bitmap downloadFromUrl(String imageURL, String fileName) {
        try {
            Log.i("renaud", "downloadFromUrl begin");
            final String extStorageDirectory = Environment
                    .getExternalStorageDirectory().toString();
            final String festivalDirectory_path = extStorageDirectory
                    + Constants.IMAGES_STORAGE_PATH;
            File imageOutputFile = new File(festivalDirectory_path, "/");
            if (imageOutputFile.exists() == false) {
                imageOutputFile.mkdirs();
            }
            File imageFile = new File(imageOutputFile, fileName);
            Log.i("renaud", "imageFileCreated");
            if (!imageFile.exists()) {
                Log.i("renaud", "imageFile do not exists");
                URL url = new URL(imageURL);
                HttpURLConnection urlConnection;
                urlConnection = (HttpURLConnection) url.openConnection();

                urlConnection.setRequestMethod("GET");
                urlConnection.setDoOutput(true);
                urlConnection.connect();

                FileOutputStream fileOutput = new FileOutputStream(
                        imageFile);
                InputStream inputStream = urlConnection.getInputStream();
                byte[] buffer = new byte[1024];
                int bufferLength = 0;
                while ((bufferLength = inputStream.read(buffer)) > 0) {
                    fileOutput.write(buffer, 0, bufferLength);
                }

                fileOutput.close();
                Log.i("renaud", "image stored");
                return decodeFile(imageFile.getAbsoluteFile());
            } else {
                Log.i("renaud", "imageFile do exists");
                Bitmap bm = decodeFile(imageFile.getAbsoluteFile());
                if (bm == null) {
                    imageFile.delete();
                    return null;
                }
                return bm;
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}

 private Bitmap decodeFile(File f) {
        try {
            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f), null, o);

            // The new size we want to scale to
            final int REQUIRED_SIZE = 150;

            // Find the correct scale value. It should be the power of 2.
            int width_tmp = o.outWidth, height_tmp = o.outHeight;
            int scale = 1;
            while (true) {
                if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
                    break;
                width_tmp /= 2;
                height_tmp /= 2;
                scale *= 2;
            }

            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);

        } catch (FileNotFoundException e) {
        }
        return null;
    }

1 个答案:

答案 0 :(得分:1)

您应该注意的一件事是,在下载数据时很少会忘记内存。内存不足总是与将输入流转换为位图时有关。因此,请将下载的输入流转换为位图的代码。下面是检查和缩小位图大小以避免内存不足的代码

try
{
img_t.setImageBitmap(btm);

}
 catch(OutOfMemoryError e)
         {

             set_photo_in_imageview(is,getRealPathFromURI(selectedImageUri));
             txt_has_data=true;
         }

private void set_photo_in_imageview(InputStream is,String path_name)
{
    BitmapFactory.Options options=new BitmapFactory.Options();
    options.inSampleSize = 8;
    options.inJustDecodeBounds = true;

    Bitmap preview_bitmap=BitmapFactory.decodeStream(is,null,options);

    final int REQUIRED_SIZE=70;

    int width_tmp=options.outWidth, height_tmp=options.outHeight;
    int scale=1;
    while(true){
        if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
            break;
        width_tmp/=2;
        height_tmp/=2;
        scale*=2;
    }

    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize=scale;
    Bitmap btm=BitmapFactory.decodeStream(is, null, o2);
    img_t.setImageBitmap(btm);
    txt_photo_id.setVisibility(TextView.VISIBLE);
    String any[]=path_name.split("/");
    if(any.length==0)
    {
        txt_photo_id.setText(path_name);
    }
    else
    {
        txt_photo_id.setText(any[any.length-1]);    
    }
    //txt_photo_id.setText(path_name);
}