如何在GridView中加载更多10,000个图像?

时间:2017-12-01 13:44:37

标签: android image file

我尝试制作图库管理器并加载我尝试使用位图和毕加索的所有图像但是当图像大小超过3000个应用程序崩溃并且在毕加索显示为outofmemoryerror错误 我增加了我的代码的大小 这是我的清单

 <application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:largeHeap="true"
    android:theme="@style/AppTheme">

在我的gridel文件中

dexOptions {
    javaMaxHeapSize "8g"
}

在我的gridle.property文件中

org.gradle.jvmargs=-Xmx3536m

现在请大家为您推荐一下我应该使用哪种技术以及File Explores正在使用哪种技术....

这是我的代码

    public class MainActivity extends AppCompatActivity {
GridView gridView;
    ArrayList<String> thhumbnail = new ArrayList<String>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    gridView = (GridView) findViewById(R.id.gridview);
    getFromSdcard(new File("/storage/emulated/0/DCIM/Camera"));
    gridView.setAdapter(new ImageAdapter(MainActivity.this, thhumbnail,false));

}

public void getFromSdcard( File thumbnail)
{

    thhumbnail.clear();
    File[] listFilethumbnail;

    try {
        if (thumbnail.isDirectory()) {
            listFilethumbnail = thumbnail.listFiles();

            for (int i = 0; i < listFilethumbnail.length; i++) {
                thhumbnail.add(listFilethumbnail[i].getAbsolutePath());


            }
        }
    }catch (Exception e){
        e.printStackTrace();
    }
}

和我的adpter文件

public class ImageAdapter extends BaseAdapter {
Bitmap bmp;
final int THUMBSIZE = 64;
int count=0;
int pos_path=-1;
boolean bms=false;
LayoutInflater inflater;
private static final int PADDING = 8;
public static  ArrayList<String> chekbox_array=new ArrayList<>();
public static ArrayList<String> chekbox_array1=new ArrayList<>();

private static final int WIDTH = 250;
private static final int HEIGHT = 250;
private Activity mContext;
private List<String> mThumbIds;


public ImageAdapter(Activity activity, List<String> ids, boolean bm){
    this.inflater = LayoutInflater.from(activity);
    mContext = activity;
    this.mThumbIds = ids;
    this.bms=bm;
}


@Override
public int getCount() {
    return mThumbIds.size();
}

@Override
public Object getItem(int position) {
    return null;
}

// Will get called to provide the ID that
// is passed to OnItemClickListener.onItemClick()
@Override
public long getItemId(int position) {
    return position;
}

// create a new ImageVie for each item referenced by the Adapter
@Override
public View getView(final int position, View convertView, ViewGroup parent) {


    convertView = inflater.inflate(R.layout.songs_cat_item,null);
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.songs_cat_item,null);
    }
    TextView textView = (TextView) convertView.findViewById(R.id.image_adapter_texxt);
    ImageView imageView = (ImageView)convertView.findViewById(R.id.image_adapter_gride);
    final CheckBox checkBox=(CheckBox)convertView.findViewById(R.id.check_box_adapter_gride);



    imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    File fm=new File(mThumbIds.get(position));
    String image_name=fm.getName(),file_name=fm.getName();

    if (file_name.length() > 11)
    file_name=file_name.substring(0,11);

    textView.setText(file_name);



    Log.d("bitmap",String.valueOf(mThumbIds.get(position))+"\n");
    if (image_name.endsWith(".jpg")) {
        Picasso.with(mContext).load("file://"+mThumbIds.get(position)).error(R.drawable.ic_launcher_background).into(imageView);

    }
    else {
    }

            if (pos_path != -1){
if (pos_path == position){
    chekbox_array.add(mThumbIds.get(position));
    checkBox.setChecked(true);
    Log.d("arraylistvaluenormal",String.valueOf(chekbox_array));
}else
checkBox.setChecked(false);

    }else
    checkBox.setChecked(false);
    return convertView;
}

2 个答案:

答案 0 :(得分:1)

适配器代码存在一些问题。

首先,您应该告诉Picasso调整图像大小,以便它不会将完整大小的图像加载到设备内存中。

Picasso.with(context)
       .load(file)
       .resize(width, height) // scales down the image as it's being loaded resulting in less memory used
       .onlyScaleDown() // self explanatory, optional
       .fit() // optional, other options include centerCrop()/centerInside()
       .into(imageView);

另一个问题是,您正在调用每个时间getView的新布局。如果Picasso仍处于加载图像的过程中,这将导致Picasso保留对先前布局的引用。

通常,如何使用convertView,检查它是否为空,然后为布局文件充气。

@Override
public View getView(int position, View convertView, ViewGroup parent) {
     if (convertView == null) {
         convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_layout, parent, false);
     }
     // do stuff
     return convertView;
}

Picasso将保留对其正在加载图像的目标的引用,如果有后续调用将另一个图像加载到同一目标中,则它将取消先前的加载请求并继续使用新的加载请求。

由于您每次调用getView时都会创建一个新布局,Picasso将永远不会取消之前的请求,并会保留对其已排入队列的所有视图的引用,从而导致大量正在使用的内存量。

答案 1 :(得分:0)

您必须使用缩略图并通过下载获得大图片