Je reçois Java.lang.OutOfMemoryError , chaque fois que j'appelle ploadActivity.Java
Le numéro de ligne 176 est:
Bitmap bm = BitmapFactory.decodeFile(strPath);
Voir mon journal:
12-07 17:57:10.585: E/AndroidRuntime(16708): FATAL EXCEPTION: main
12-07 17:57:10.585: E/AndroidRuntime(16708): Java.lang.OutOfMemoryError
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.graphics.BitmapFactory.decodeStream(BitmapFactory.Java:650)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.graphics.BitmapFactory.decodeFile(BitmapFactory.Java:389)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.graphics.BitmapFactory.decodeFile(BitmapFactory.Java:449)
12-07 17:57:10.585: E/AndroidRuntime(16708): at com.example.camera.UploadActivity$ImageAdapter.getView(UploadActivity.Java:176)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.AbsListView.obtainView(AbsListView.Java:2465)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.ListView.makeAndAddView(ListView.Java:1775)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.ListView.fillDown(ListView.Java:678)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.ListView.fillFromTop(ListView.Java:739)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.ListView.layoutChildren(ListView.Java:1628)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.AbsListView.onLayout(AbsListView.Java:2300)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.View.layout(View.Java:14063)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewGroup.layout(ViewGroup.Java:4607)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.RelativeLayout.onLayout(RelativeLayout.Java:948)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.View.layout(View.Java:14063)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewGroup.layout(ViewGroup.Java:4607)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.FrameLayout.onLayout(FrameLayout.Java:448)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.View.layout(View.Java:14063)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewGroup.layout(ViewGroup.Java:4607)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.LinearLayout.setChildFrame(LinearLayout.Java:1655)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.LinearLayout.layoutVertical(LinearLayout.Java:1513)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.LinearLayout.onLayout(LinearLayout.Java:1426)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.View.layout(View.Java:14063)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewGroup.layout(ViewGroup.Java:4607)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.widget.FrameLayout.onLayout(FrameLayout.Java:448)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.View.layout(View.Java:14063)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewGroup.layout(ViewGroup.Java:4607)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewRootImpl.performLayout(ViewRootImpl.Java:1996)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewRootImpl.performTraversals(ViewRootImpl.Java:1817)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewRootImpl.doTraversal(ViewRootImpl.Java:1114)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.Java:4520)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.Choreographer$CallbackRecord.run(Choreographer.Java:725)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.Choreographer.doCallbacks(Choreographer.Java:555)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.Choreographer.doFrame(Choreographer.Java:525)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.Java:711)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.os.Handler.handleCallback(Handler.Java:615)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.os.Handler.dispatchMessage(Handler.Java:92)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.os.Looper.loop(Looper.Java:137)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Android.app.ActivityThread.main(ActivityThread.Java:4921)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Java.lang.reflect.Method.invokeNative(Native Method)
12-07 17:57:10.585: E/AndroidRuntime(16708): at Java.lang.reflect.Method.invoke(Method.Java:511)
12-07 17:57:10.585: E/AndroidRuntime(16708): at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:1036)
12-07 17:57:10.585: E/AndroidRuntime(16708): at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:803)
12-07 17:57:10.585: E/AndroidRuntime(16708): at dalvik.system.NativeStart.main(Native Method)
ploadActivity.Java:-
public class ImageAdapter extends BaseAdapter
{
private Context context;
public ImageAdapter(Context c)
{
// TODO Auto-generated method stub
context = c;
}
public int getCount() {
// TODO Auto-generated method stub
return ImageList.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_upload, null);
}
// ColImgName
TextView txtName = (TextView) convertView.findViewById(R.id.ColImgName);
strPath = ImageList.get(position).toString();
// Get File Name
fileName = strPath.substring( strPath.lastIndexOf('/')+1, strPath.length() );
File file = new File(strPath);
@SuppressWarnings("unused")
long length = file.length();
txtName.setText(fileName);
// Image Resource
ImageView imageView = (ImageView) convertView.findViewById(R.id.ColImgPath);
Bitmap bm = BitmapFactory.decodeFile(strPath);
imageView.setImageBitmap(bm);
// ColStatus
final ImageView txtStatus = (ImageView) convertView.findViewById(R.id.ColStatus);
txtStatus.setImageResource(R.drawable.bullet_button);
// progressBar
final ProgressBar progress = (ProgressBar) convertView.findViewById(R.id.progressBar);
progress.setVisibility(View.GONE);
//btnUpload
final ImageButton btnUpload = (ImageButton) convertView.findViewById(R.id.btnUpload);
btnUpload.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Upload
btnUpload.setEnabled(false);
startUpload(position);
}
});
return convertView;
}
}
Vous devez recycler l'objet Bitmap.
Bitmap bm = BitmapFactory.decodeFile(strPath);
imageView.setImageBitmap(bm);
Après les lignes de code ci-dessus dans votre vue get, ajoutez simplement le code écrit ci-dessous /// recyclez maintenant votre bitmap, cela libérera de la mémoire à chaque itération
if(bm!=null)
{
bm.recycle();
bm=null;
}
Après cela aussi si vous obtenez la même erreur le
Remplacer le code ci-dessous
Bitmap bm = BitmapFactory.decodeFile(strPath);
imageView.setImageBitmap(bm);
avec
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap bm = BitmapFactory.decodeFile(strPath,options);
imageView.setImageBitmap(bm);
Utilisez inSampleSize pour charger des images bitmap en mémoire. L'utilisation de puissances de 2 pour les valeurs inSampleSize est plus rapide et plus efficace pour le décodeur. Cependant, si vous prévoyez de mettre en cache les versions redimensionnées dans la mémoire ou sur le disque, cela vaut généralement la peine d'être décodé aux dimensions d'image les plus appropriées pour économiser de l'espace.
Pour plus d'informations, voir Chargement Grands bitmaps efficacement
Utilisez-le dans le fichier manifeste de la balise Application
Android:largeHeap="true"
avant d'appeler Bitmap bm = BitmapFactory.decodeFile (strPath);
appelez cela. Bitmap bm = decodeSampledBitmapFromResource (strPath, reqWidth, reqHeight);
si vous obtenez à nouveau Java.lang.OutOfMemoryError, faites le moi savoir
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and
// keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(String strPath,int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(strPath, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options,reqWidth,
reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(strPath, options);;
}
C'est un problème d'optimisation pour votre application. Vous obtenez OutOfMemoryError parce que lorsque vous effectuez BitmapFactory.decodeFile (strPath) Android essaie d'allouer de la mémoire pour ce bitmap. Dans votre cas, le système ne peut pas trouver suffisamment d'espace libre à allouer et c'est pourquoi vous obtenez cette erreur.
Maintenant, comme je peux le voir dans votre code, vous essayez d'afficher la liste des images à l'aide d'ImageAdapter. Dans ce cas, votre image doit avoir une largeur et une hauteur plus petites que l'image réelle.
Pour vous donner une idée plus généralisée, voici ce qui se passe:
Dans ce scénario, bien que notre largeur d'image-hauteur soit de 100 * 100, mais nous essayons de définir l'image 800 * 800 comme arrière-plan. Et ce n'est certainement pas un moyen efficace car le système allouera de la mémoire pour une image de 800 * 800px alors que 100 * 100 le ferait.
C'est pourquoi, avant de décoder le bitmap, vous devez échantillonner le bitmap afin que seulement 100 * 100 de mémoire soient alloués.
Vous trouverez une version plus détaillée de cette explication ici
J'ai eu le même problème. J'ai incorporé toutes les suggestions ci-dessus, mais j'avais toujours le problème de Java.lang.outOfMemoryError. Après de nombreux ajustements, ce qui a finalement fonctionné a été de réduire les dimensions (et la taille) de l'image. À l'origine, j'avais des images de dimensions 800 x 1000 sortes. Je les ai redimensionnés à environ 60 x 80 (parce que c'est ce dont j'avais besoin), et cela a fonctionné!
Donc, en plus de suivre tous les conseils que vous obtenez sur stackoverflow et d'autres sites à ce sujet, faites également une vérification de base de vos tailles et dimensions d'image. Vous fera économiser beaucoup de maux de tête.