2

Je dois charger toutes les images de la carte SD en vue décalée ... quand je règle le nombre 100, les images sont affichées en quinconce, mais pour beaucoup d'images (par exemple, 700/800). AsyncTask mais il montre l'erreur doinbackground s'il vous plaît aidez-moi à sortir ceci.AsyncTask OutOfMemoryError: la taille de l'image dépasse le budget de la machine

import android.content.Context; 
import android.database.Cursor; 
import android.graphics.Bitmap; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.provider.MediaStore; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.RecyclerView; 
import android.support.v7.widget.StaggeredGridLayoutManager; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ImageView; 
import java.util.ArrayList; 
import java.util.List; 

public class MainActivity extends AppCompatActivity 
{ 
    private StaggeredGridLayoutManager staggeredGridLayoutManager; 
    MyAdapter myAdapter; 
    List<ItemData> grid_view_item = new ArrayList<>(); 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); 
    recyclerView.setHasFixedSize(true); 

staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); 
recyclerView.setLayoutManager(staggeredGridLayoutManager); 
      //call the LoadImage 
      new LoadImage().execute(); 
      myAdapter = new MyAdapter(MainActivity.this, grid_view_item); 
      recyclerView.setAdapter(myAdapter); 

     } 

c'est la classe AsncTask.

class LoadImage extends AsyncTask<Void,Void,Void> 
     { 
      private int count; 
      private Bitmap[] thumbnails; 
      private boolean[] thumbnailsselection; 
      private String[] arrPath; 

      @Override 
      protected Void doInBackground(Void... params) 
      { 
       //load gallery iamges 
       final String[] columns = {MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID}; 
       final String orderBy = MediaStore.Images.Media._ID; 
       Cursor imagecursor = managedQuery(
         MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null, 
         null, orderBy); 
       int image_column_index = imagecursor.getColumnIndex(MediaStore.Images.Media._ID); 
       Log.e("COUNT ", "" + image_column_index); 
       this.count = imagecursor.getCount(); 
       Log.e("COUNT ", "" + count); 
       this.thumbnails = new Bitmap[this.count]; 
       Log.e("COUNT ", "" + thumbnails); 
       this.arrPath = new String[this.count]; 
       Log.e("COUNT ", "" + arrPath); 
       this.thumbnailsselection = new boolean[this.count]; 
       Log.e("COUNT ", "" + thumbnailsselection); 
       for (int i = 0; i < this.count; i++) { 
        imagecursor.moveToPosition(i); 
        int id = imagecursor.getInt(image_column_index); 
        int dataColumnIndex = imagecursor.getColumnIndex(MediaStore.Images.Media.DATA); 
        thumbnails[i] = MediaStore.Images.Thumbnails.getThumbnail(
          getApplicationContext().getContentResolver(), id, 
          MediaStore.Images.Thumbnails.MINI_KIND, null); 
        arrPath[i] = imagecursor.getString(dataColumnIndex); 
        grid_view_item.add(new ItemData(thumbnails[i])); 
       } 

       return null; 
      } 
     } 

est la classe Adapter.

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> 
{ 
      private List<ItemData> itemsData; 
      private Context context; 

    public MyAdapter(Context context, List<ItemData> itemsData) 
    { 
       this.itemsData = itemsData; 
       this.context = context; 
    } 

    @Override 
      public int getItemCount() { 
       return this.itemsData.size(); 
      } 

      @Override 
      public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, 
                  int viewType) { 
       // create a new view 
       View itemLayoutView = LayoutInflater.from(parent.getContext()) 
         .inflate(R.layout.staggered_view_image, null); 

       // create ViewHolder 

       ViewHolder viewHolder = new ViewHolder(itemLayoutView); 
       return viewHolder; 
      } 

      // Replace the contents of a view (invoked by the layout manager) 
      @Override 
      public void onBindViewHolder(ViewHolder viewHolder, final int position) { 

       viewHolder.img.setImageBitmap(itemsData.get(position).getImage()); 

      } 


      // inner class to hold a reference to each item of RecyclerView 
      public class ViewHolder extends RecyclerView.ViewHolder { 
       public ImageView img; 

       public ViewHolder(View itemLayoutView) { 
        super(itemLayoutView); 
        img = (ImageView) itemLayoutView.findViewById(R.id.gallery_photo); 
       } 
      } 
} 
} 

LogCat.

1 
12-30 08:49:50.329 2902-2935/com.staggeredgridview E/COUNT: 775 
12-30 08:49:50.329 2902-2935/com.staggeredgridview E/COUNT: [Landroid.graphics.Bitmap;@40513478 
12-30 08:49:50.329 2902-2935/com.staggeredgridview E/COUNT: [Ljava.lang.String;@405187f8 
12-30 08:49:50.329 2902-2935/com.staggeredgridview E/COUNT: [[email protected] 
12-30 08:50:24.319 2902-2935/com.staggeredgridview E/dalvikvm-heap: 153600-byte external allocation too large for this process. 
12-30 08:50:24.369 2902-2935/com.staggeredgridview E/GraphicsJNI: VM won't let us allocate 153600 bytes 
12-30 08:50:24.369 2902-2935/com.staggeredgridview D/skia: libjpeg error 105 < Ss=%d, Se=%d, Ah=%d, Al=%d> from allocPixelRef [320 240] 
12-30 08:50:24.369 2902-2935/com.staggeredgridview D/skia: --- decoder->decode returned false 
12-30 08:50:24.369 2902-2935/com.staggeredgridview E/MediaStore: failed to allocate memory for thumbnail content://media/external/images/thumbnails/615; java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
12-30 08:50:24.539 2902-2935/com.staggeredgridview E/dalvikvm-heap: 153600-byte external allocation too large for this process. 
12-30 08:50:24.589 2902-2935/com.staggeredgridview E/GraphicsJNI: VM won't let us allocate 153600 bytes 
12-30 08:50:24.589 2902-2935/com.staggeredgridview D/skia: libjpeg error 105 < Ss=%d, Se=%d, Ah=%d, Al=%d> from allocPixelRef [320 240] 
12-30 08:50:24.589 2902-2935/com.staggeredgridview D/skia: --- decoder->decode returned false 
12-30 08:50:24.589 2902-2935/com.staggeredgridview E/MediaStore: failed to allocate memory for thumbnail content://media/external/images/thumbnails/615; java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
12-30 08:50:24.599 2902-2935/com.staggeredgridview V/MediaStore: Create the thumbnail in memory: origId=639, kind=1, isVideo=false 
12-30 08:50:24.749 2902-2935/com.staggeredgridview E/dalvikvm-heap: 307200-byte external allocation too large for this process. 
12-30 08:50:24.799 2902-2935/com.staggeredgridview E/GraphicsJNI: VM won't let us allocate 307200 bytes 
12-30 08:50:24.799 2902-2935/com.staggeredgridview D/skia: libjpeg error 105 < Ss=%d, Se=%d, Ah=%d, Al=%d> from allocPixelRef [320 240] 
12-30 08:50:24.799 2902-2935/com.staggeredgridview D/skia: --- decoder->decode returned false 
12-30 08:50:24.809 2902-2935/com.staggeredgridview W/dalvikvm: threadid=9: thread exiting with uncaught exception (group=0x40018578) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime: java.lang.RuntimeException: An error occured while executing doInBackground() 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at android.os.AsyncTask$3.done(AsyncTask.java:200) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at java.lang.Thread.run(Thread.java:1019) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime: Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:508) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at android.media.ThumbnailUtils.createThumbnailFromEXIF(ThumbnailUtils.java:489) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at android.media.ThumbnailUtils.createImageThumbnail(ThumbnailUtils.java:102) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at android.provider.MediaStore$InternalThumbnails.getThumbnail(MediaStore.java:455) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at android.provider.MediaStore$Images$Thumbnails.getThumbnail(MediaStore.java:791) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at com.staggeredgridview.MainActivity$LoadImage.doInBackground(MainActivity.java:73) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at com.staggeredgridview.MainActivity$LoadImage.doInBackground(MainActivity.java:42) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at android.os.AsyncTask$2.call(AsyncTask.java:185) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at java.util.concurrent.FutureTask.run(FutureTask.java:138)  
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)  
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)  
12-30 08:50:24.829 2902-2935/com.staggeredgridview E/AndroidRuntime:  at java.lang.Thread.run(Thread.java:1019)  
+0

votre logcat – droidev

+0

publier logcat montre les thumnails [i] erreur .. @ Vivid Vervet –

+2

java.lang.OutOfMemoryError: la taille du bitmap dépasse le budget VM ...... ce est le problème vérifier ceci http://stackoverflow.com/questions/1949066/java-lang-outofmemoryerror-bitmap-size-exceeds-vm-budget-android –

Répondre

0

pour résoudre ce problème, j'ai ajouté android:largeHeap="true" dans le fichier Android Manifest dans la demande tag..it résoudre le problème mais l'application nécessite plus tas memory..might il affecte l'autre application et la deuxième chose qu'il faut plus de temps pour charger les images

c'est le fichier manifest Android

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.staggeredgridview" > 
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 
    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:largeHeap="true" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name=".MainActivity" 
      android:label="@string/app_name" 
      android:theme="@style/AppTheme.NoActionBar" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

c'est le ..its de code final fonctionne très bien ..

import android.content.Context; 
import android.database.Cursor; 
import android.graphics.Bitmap; 
import android.os.Bundle; 
import android.provider.MediaStore; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.RecyclerView; 
import android.support.v7.widget.StaggeredGridLayoutManager; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ImageView; 
import java.util.ArrayList; 
import java.util.List; 


public class MainActivity extends AppCompatActivity { 
    private int count; 
    private Bitmap[] thumbnails; 
    private boolean[] thumbnailsselection; 
    private String[] arrPath; 
    private StaggeredGridLayoutManager staggeredGridLayoutManager; 
    MyAdapter myAdapter; 
    List<ItemData> grid_view_item = new ArrayList<>(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); 
     recyclerView.setHasFixedSize(true); 


     staggeredGridLayoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL); 
     recyclerView.setLayoutManager(staggeredGridLayoutManager); 
     myAdapter = new MyAdapter(MainActivity.this, grid_view_item); 
     recyclerView.setAdapter(myAdapter); 


     //load gallery iamges 
     final String[] columns = {MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID}; 
     final String orderBy = MediaStore.Images.Media._ID; 
     Cursor imagecursor = managedQuery(
       MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null, 
       null, orderBy); 
     int image_column_index = imagecursor.getColumnIndex(MediaStore.Images.Media._ID); 
     Log.e("COUNT ", "" + image_column_index); 
     this.count = imagecursor.getCount(); 
     Log.e("COUNT ", "" + count); 
     this.thumbnails = new Bitmap[this.count]; 
     Log.e("COUNT ", "" + thumbnails); 
     this.arrPath = new String[this.count]; 
     Log.e("COUNT ", "" + arrPath); 
     this.thumbnailsselection = new boolean[this.count]; 
     Log.e("COUNT ", "" + thumbnailsselection); 
     for (int i = 0; i < this.count; i++) { 
      imagecursor.moveToPosition(i); 
      int id = imagecursor.getInt(image_column_index); 
      int dataColumnIndex = imagecursor.getColumnIndex(MediaStore.Images.Media.DATA); 
      thumbnails[i] = MediaStore.Images.Thumbnails.getThumbnail(
        getApplicationContext().getContentResolver(), id, 
        MediaStore.Images.Thumbnails.MINI_KIND, null); 
      arrPath[i] = imagecursor.getString(dataColumnIndex); 
      grid_view_item.add(new ItemData(thumbnails[i])); 
     } 
    } 

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { 
     private List<ItemData> itemsData; 
     private Context context; 

     public MyAdapter(Context context, List<ItemData> itemsData) { 
      this.itemsData = itemsData; 
      this.context = context; 
     } 

     @Override 
     public int getItemCount() { 
      return this.itemsData.size(); 
     } 

     @Override 
     public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, 
                 int viewType) { 
      // create a new view 
      View itemLayoutView = LayoutInflater.from(parent.getContext()) 
        .inflate(R.layout.staggered_view_image, null); 

      // create ViewHolder 

      ViewHolder viewHolder = new ViewHolder(itemLayoutView); 
      return viewHolder; 
     } 

     // Replace the contents of a view (invoked by the layout manager) 
     @Override 
     public void onBindViewHolder(ViewHolder viewHolder, final int position) { 

      viewHolder.img.setImageBitmap(itemsData.get(position).getImage()); 

     } 


     // inner class to hold a reference to each item of RecyclerView 
     public class ViewHolder extends RecyclerView.ViewHolder { 
      public ImageView img; 

      public ViewHolder(View itemLayoutView) { 
       super(itemLayoutView); 
       img = (ImageView) itemLayoutView.findViewById(R.id.gallery_photo); 
      } 
     } 
    } 
} 
1

Aussi bien que j'ai commenté, vous obtenez l'erreur parce que le système d'android a une certaine limitation pour fournir la mémoire pour l'application. Si vous voulez plus de mémoire que l'allocation, vous avez défini largeHeap comme true dans le fichier manifeste. Ainsi, le système d'exploitation allouera plus de mémoire selon les besoins. Mais ce n'est pas toujours une bonne pratique. Si vous pouvez réduire la consommation de mémoire de toute façon, c'est la meilleure option. Ou il va tuer d'autres applications qui s'exécutent en arrière-plan. Donc, votre manifeste sera comme comme suit

<application 
      android:icon="@mipmap/ic_launcher" 
      android:largeHeap="true" 
      android:theme="@style/AppTheme" > 
      <activity 
       ..... 
       ....../> 
       .... 
       ... 
<application/> 
+0

Pourquoi avez-vous répondu si OP déjà répondu à la solution? –

+0

J'utilise l'application mobile SO maintenant, donc je dint remarque qu'en fait :-( – droidev

+0

Je veux dire, il n'y a rien de mal à votre réponse. –