0

我正在从我的手机图库中加载图像并将其加载到我的应用程序库中,但是每次我运行该应用程序时它都会强制关闭。

我的代码:

 public class ImageActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.imagelayout);

    Gallery gallery = (Gallery) findViewById(R.id.gallery);
    gallery.setAdapter(new ImageAdapter(this));


    gallery.setOnItemClickListener(new OnItemClickListener() 
    {
        public void onItemClick(AdapterView parent, 
        View v, int position, long id) 
        {                
            Toast.makeText(getBaseContext(), 
                    "pic" + (position + 1) + " selected", 
                    Toast.LENGTH_SHORT).show();
        }
    });
}

}

 public class ImageLoader {

    private List<String> ImageFiles = new ArrayList<String>();
    private static final String CAMERA_IMAGE_BUCKET_NAME = Environment.getExternalStorageDirectory().toString()+ "/DCIM/Camera";    
    private File file;

    public ImageLoader(){
        ReadImages();
    }

    public List<String> getImageFiles(){
        return ImageFiles;
    }

    private void ReadImages(){
        file = new File(CAMERA_IMAGE_BUCKET_NAME);
        File[] URIs = file.listFiles(new ImageFileFilter());
        for(int x = 0; x < URIs.length; x++){
            File file = URIs[x];
            ImageFiles.add(file.getPath());
        }
    }

    /**
     * Image File Filter Class
     */
    public class ImageFileFilter implements FileFilter{

        private final String[] AndroidExtensions = new String[] {"jpg", "png"};

        public boolean accept(File pathname) {
            for (String extension : AndroidExtensions)
            {
              if (pathname.getName().toLowerCase().endsWith(extension))
              {
                return true;
              }
            }
            return false;
        }

    }

}

public class ImageAdapter extends BaseAdapter {

     private Context context;
     private int itemBackground;
     List<String> images;
     ImageLoader loader; 


     public ImageAdapter(Context c){
         loader = new ImageLoader();
         images = loader.getImageFiles();
         context = c;
         //---setting the style---
         TypedArray a = c.obtainStyledAttributes(R.styleable.gallery);
         itemBackground = a.getResourceId(
             R.styleable.gallery_android_galleryItemBackground, 0);
         a.recycle();  
     }


    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return images.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }


    //---returns an ImageView view---
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView = new ImageView(context);
        try{
            Bitmap bm = BitmapFactory.decodeFile(images.get(position).toString());  

            imageView.setImageBitmap(bm); 
        }
        catch(Exception e){
            Log.e("DEBUGTAG", "Remtoe Image Exception", e);
        }

        imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
        imageView.setLayoutParams(new Gallery.LayoutParams(150, 100));
        imageView.setBackgroundResource(itemBackground);
        return imageView;
    }
}

谢谢你的帮助!

Stack trace:
Thread [<1> main] (Suspended (exception OutOfMemoryError))  
    BitmapFactory.decodeFile(String, BitmapFactory$Options) line: 277   
    BitmapFactory.decodeFile(String) line: 296  
    ImageAdapter.getView(int, View, ViewGroup) line: 63 
    Gallery.makeAndAddView(int, int, int, boolean) line: 745    
    Gallery.fillToGalleryRight() line: 697  
    Gallery.layout(int, boolean) line: 628  
    Gallery.onLayout(boolean, int, int, int, int) line: 336 
    Gallery(View).layout(int, int, int, int) line: 7035 
    LinearLayout.setChildFrame(View, int, int, int, int) line: 1249 
    LinearLayout.layoutVertical() line: 1125    
    LinearLayout.onLayout(boolean, int, int, int, int) line: 1042   
    LinearLayout(View).layout(int, int, int, int) line: 7035    
    LinearLayout.setChildFrame(View, int, int, int, int) line: 1249 
    LinearLayout.layoutHorizontal() line: 1238  
    LinearLayout.onLayout(boolean, int, int, int, int) line: 1044   
    LinearLayout(View).layout(int, int, int, int) line: 7035    
    FrameLayout.onLayout(boolean, int, int, int, int) line: 333 
    FrameLayout(View).layout(int, int, int, int) line: 7035 
    PhoneWindow$DecorView(FrameLayout).onLayout(boolean, int, int, int, int) line: 333  
    PhoneWindow$DecorView(View).layout(int, int, int, int) line: 7035   
    ViewRoot.performTraversals() line: 1045 
    ViewRoot.handleMessage(Message) line: 1727  
    ViewRoot(Handler).dispatchMessage(Message) line: 99 
    Looper.loop() line: 123 
    ActivityThread.main(String[]) line: 4627    
    Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]  
    Method.invoke(Object, Object...) line: 521  
    ZygoteInit$MethodAndArgsCaller.run() line: 858  
    ZygoteInit.main(String[]) line: 616 
    NativeStart.main(String[]) line: not available [native method]  
4

2 回答 2

1

OutOfMemoryError 通常是因为您尝试解码压缩图像,但这样做会填满堆。解压缩后,智能手机上的图库图像可能会很大(几 MB 大小)。您需要使用文件的压缩版本或一次只使用图片的片段。

于 2011-02-26T14:12:54.893 回答
1

我将 getView 方法更改为:

public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView = new ImageView(context);
    try{
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inTempStorage = new byte[16*1024];
        Bitmap bm = this.decodeFile(images.get(position).toString());  

        imageView.setImageBitmap(bm); 
        //bm.recycle();
        bm = null;
        System.gc();
    }
    catch(Exception e){
        Log.e("DEBUGTAG", "Remtoe Image Exception", e);
    }

    imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
    imageView.setLayoutParams(new Gallery.LayoutParams(150, 100));
    imageView.setBackgroundResource(itemBackground);
    return imageView;
}

我使用了从链接获得的新解码方法

private Bitmap decodeFile(String 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=70;

        //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;
}
于 2011-02-26T15:07:00.650 回答