在Android中,在GridView中显示文件中的图像非常慢

时间:2013-10-10 10:30:46

标签: android gridview

我有两个问题:

  1. 在gridview中显示图像之前的延迟很长:15秒!我不知道如何解决这个问题。

  2. 当在gridview中加载图像并且我尝试向下(或向上)以查看其余图像时,移动电话需要很长时间才能显示它们。此外,如果我滚动得非常快,应用程序就会停止。

  3. 备注:e var用于为每个跳跃+1(绿色/蓝色/绿色......)背景提供不同的颜色。

    提前致谢,在这里代码:

    代码: res / layout / main_activity.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".MainActivity" >
    
    
    
         <GridView
        android:id="@+id/PhoneImageGrid"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:columnWidth="90dp"
        android:gravity="center"
        android:horizontalSpacing="10dp"
        android:numColumns="auto_fit"
        android:stretchMode="columnWidth"
        android:verticalSpacing="5dp" />
    
    
    
    </RelativeLayout>
    

    代码: MainActivity.java

    public class MainActivity extends Activity {
    
        private int count;
        private Bitmap[] thumbnails;
        private boolean[] thumbnailsselection;
        private String[] arrPath;
        private ImageAdapter imageAdapter;
        ArrayList<String> f = new ArrayList<String>();// list of file paths
         int e=0; // To change the background color 
        String[] Files;
        ImageView selection;
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // get images paths and store them in f
                getFromSdcard();
    
               GridView imagegrid = (GridView) findViewById(R.id.PhoneImageGrid);
    
                imagegrid.setAdapter(new ImageAdapter(this));
    
        }
    
        /*GET images paths */
        public void getFromSdcard()
        {
    
            File file=  new File("mnt/sdcard/DCIM/100ANDRO");
    
                if (file.exists())
                {
                    Files = file.list();
    
                    for (int i = 0; i < Files.length; i++)
                    {
                        f.add(file.getAbsolutePath() + File.separator + Files[i]);
                  }
    
                }
    
        }
    
    
        public class ImageAdapter extends BaseAdapter {
    
            Context ctxt;
    
            public ImageAdapter(Context c) {
    
                    this.ctxt=c;
                    }
    
            public int getCount() {
                return f.size();
            }
    
            public Object getItem(int position) {
                return position;
            }
    
            public long getItemId(int position) {
                return position;
            }
    
    
            public void setColorType(){
                if(e==0)
                    e= 1;
                else{e= 0;}
    
            }
            public View getView(int position, View convertView, ViewGroup parent) {
    
    
                ImageView c;
    
                if (convertView == null) {
                    c= new ImageView(ctxt);
    
                    //Bitmap myBitmap = BitmapFactory.decodeFile(f.get(position));// Files[position]
                    c.setLayoutParams(new GridView.LayoutParams(80,80));
                    c.setScaleType(ScaleType.CENTER_CROP);
                    c.setPadding(8,8,8,8);
    
                    if(e==0){
                         c.setBackgroundColor( -65536);
                         setColorType();
                        }
                    else{
                        setColorType();
                        c.setBackgroundColor( -16711936);
                    }
    
                }
                else {
                    c= (ImageView) convertView;
    
                    if(e==0){
                         c.setBackgroundColor( 00000);
                         setColorType();
                        }
    
                }
    
                Bitmap myBitmap = decodeFile(new File(f.get(position)));
                c.setImageBitmap(myBitmap);
    
                return c;
            }
    
    
        }
    
    
    
    // To solve the issue of uploading image and avoid error ** Out of memory   
    
        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=70;
    
                //Find the correct scale value. It should be the power of 2.
                int scale=1;
                while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
                    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;
        }
    
    
    }
    

3 个答案:

答案 0 :(得分:4)

替换这些行

Bitmap myBitmap = decodeFile(new File(f.get(position)));
c.setImageBitmap(myBitmap);

if(c.getTag() != null) {
    ((ImageGetter) c.getTag()).cancel(true);
}
ImageGetter task = new ImageGetter(c) ;
task.execute(new File(f.get(position)));
c.setTag(task);

并创建此类ImageGetter,以便在后台获取图片:

public class ImageGetter extends AsyncTask<File, Void, Bitmap> {
    private ImageView iv;
    public ImageGetter(ImageView v) {
        iv = v;
    }
    @Override
    protected Bitmap doInBackground(File... params) {
        return decodeFile(params[0]);
    }
    @Override
    protected void onPostExecute(Bitmap result) {
        super.onPostExecute(result);
        iv.setImageBitmap(result);
    }
}

答案 1 :(得分:0)

我可能错了,但是如果你在线程中完成所有的加载部分,我认为它会更快,更可扩展。在适配器中,每个图像都将加载到线程中(例如,在加载时,您可以在gridview单元格中显示进度条)。线程完成后,您只需将网格视图单元格与图像内容交换。当然,用户可以比线程加载图像更快地滑动网格视图,因此您必须将线程附加到单元格,并确保只有一个线程适用于一个单元格,因此它们不会互相交换工作结果。

答案 2 :(得分:0)

用以下代码替换您的代码

public class MainActivity extends Activity {

private int count;
private Bitmap[] thumbnails;
private boolean[] thumbnailsselection;
private String[] arrPath;
private ImageAdapter imageAdapter;
ArrayList<String> f = new ArrayList<String>();// list of file paths
 int e=0; // To change the background color 
String[] Files;
ImageView selection;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // get images paths and store them in f
        getFromSdcard();

       GridView imagegrid = (GridView) findViewById(R.id.PhoneImageGrid);

        imagegrid.setAdapter(new ImageAdapter(this));

}

/*GET images paths */
public void getFromSdcard()
{

    File file=  new File("mnt/sdcard/DCIM/100ANDRO");

        if (file.exists())
        {
            Files = file.list();

            for (int i = 0; i < Files.length; i++)
            {
                f.add(file.getAbsolutePath() + File.separator + Files[i]);
          }

        }

}


public class ImageAdapter extends BaseAdapter {

    Context ctxt;

    public ImageAdapter(Context c) {

            this.ctxt=c;
            }

    public int getCount() {
        return f.size();
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }


    public void setColorType(){
        if(e==0)
            e= 1;
        else{e= 0;}

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


        ImageView c;

        if (convertView == null) {
            c= new ImageView(ctxt);

            //Bitmap myBitmap = BitmapFactory.decodeFile(f.get(position));// Files[position]
            c.setLayoutParams(new GridView.LayoutParams(80,80));
            c.setScaleType(ScaleType.CENTER_CROP);
            c.setPadding(8,8,8,8);

            if(e==0){
                 c.setBackgroundColor( -65536);
                 setColorType();
                }
            else{
                setColorType();
                c.setBackgroundColor( -16711936);
            }

        }
        else {
            c= (ImageView) convertView;

            if(e==0){
                 c.setBackgroundColor( 00000);
                 setColorType();
                }

        }

        Bitmap myBitmap = decodeFile(new File(f.get(position)));
        c.setImageBitmap(myBitmap);

        return c;
    }


}

//解决上传图片问题,避免错误**内存不足

private Bitmap decodeFile(File f){
    try {
        //Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inSampleSize = 4;
        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 scale=1;
        while(o.outWidth/scale/2>=REQUIRED_SIZE && o.outHeight/scale/2>=REQUIRED_SIZE)
            scale*=2;

        //Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = 4;


        return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
    } catch (FileNotFoundException e) {}
    return null;
}

}

Just changed  o2.inSampleSize = 4; and  o.inSampleSize = 4;

同时更改以下代码

    BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 4;
        Bitmap myBitmap=BitmapFactory.decodeFile(new File(f.get(position), options);
Bitmap myBitmap2=Bitmap.createScaledBitmap(myBitmap, 100, 100, true);
                                c.setImageBitmap(myBitmap2);

替换Bitmap myBitmap = decodeFile(new File(f.get(position))); c.setImageBitmap(myBitmap);