Dans mon application lorsque j'essaye de le lancer, Forcer la fermeture et l'erreur pointant la ligne "setContentView (R.layout.Menu);" de la mise en page. Et dans le fichier XML, il montre la vue d'image "OutOfMemoryError" dans ma mise en page. Je suis vraiment confus. Veuillez me guider pour un déménagement ultérieur.
Modifié:
Mon application utilise une base de données et, à la toute première fois, elle analyse des données XML et les insère dans la base de données Sqlite. Mon problème Outofmemory ne se produit que la première fois. La deuxième fois, cela fonctionne bien. J'ai essayé System.gc (). Y a-t-il un problème à ce sujet.
Ceci est mon journal:
E/dalvikvm-heap(2712): 105376-byte external allocation too large for this process.
VM won't let us allocate 105376 bytes
FATAL EXCEPTION: main
Java.lang.RuntimeException: Unable to start activity ComponentInfo{com.Test/com.Test.Menu}: Android.view.InflateException: Binary XML file line #13: Error inflating class <unknown>
at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:1647)
at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:1663)
at Android.app.ActivityThread.access$1500(ActivityThread.Java:117)
at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:931)
at Android.os.Handler.dispatchMessage(Handler.Java:99)
at Android.os.Looper.loop(Looper.Java:130)
at Android.app.ActivityThread.main(ActivityThread.Java:3683)
at Java.lang.reflect.Method.invokeNative(Native Method)
at Java.lang.reflect.Method.invoke(Method.Java:507)
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:839)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:597)
at dalvik.system.NativeStart.main(Native Method)
Caused by: Android.view.InflateException: Binary XML file line #13: Error inflating class <unknown>
at Android.view.LayoutInflater.createView(LayoutInflater.Java:518)
at com.Android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.Java:56)
at Android.view.LayoutInflater.createViewFromTag(LayoutInflater.Java:568)
at Android.view.LayoutInflater.rInflate(LayoutInflater.Java:623)
at Android.view.LayoutInflater.rInflate(LayoutInflater.Java:626)
at Android.view.LayoutInflater.inflate(LayoutInflater.Java:408)
at Android.view.LayoutInflater.inflate(LayoutInflater.Java:320)
at Android.view.LayoutInflater.inflate(LayoutInflater.Java:276)
at com.Android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.Java:207)
at Android.app.Activity.setContentView(Activity.Java:1657)
at com.Test.Menu.onCreate(Menu.Java:32)
at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1047)
at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:1611)
... 11 more
Caused by: Java.lang.reflect.InvocationTargetException
at Java.lang.reflect.Constructor.constructNative(Native Method)
at Java.lang.reflect.Constructor.newInstance(Constructor.Java:415)
at Android.view.LayoutInflater.createView(LayoutInflater.Java:505)
... 23 more
Caused by: Java.lang.OutOfMemoryError: bitmap size exceeds VM budget
at Android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at Android.graphics.BitmapFactory.decodeStream(BitmapFactory.Java:460)
at Android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.Java:336)
at Android.graphics.drawable.Drawable.createFromResourceStream(Drawable.Java:697)
at Android.content.res.Resources.loadDrawable(Resources.Java:1709)
at Android.content.res.TypedArray.getDrawable(TypedArray.Java:601)
at Android.widget.ImageView.<init>(ImageView.Java:118)
at Android.widget.ImageView.<init>(ImageView.Java:108)
Voici mon code XML:
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
<RelativeLayout
Android:id="@+id/RL_Title"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="8"
Android:onClick="onTitleClick" >
<ImageView
Android:id="@+id/Img_Title_bg"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:scaleType="center"
Android:src="@drawable/title_bg" />
<Button
Android:id="@+id/Btn_Title"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_centerVertical="true"
Android:layout_marginRight="5dp"
Android:background="@drawable/title_al"
Android:drawableRight="@drawable/pro"
Android:gravity="center"
Android:onClick="onTitleClick" />
</RelativeLayout>
<RelativeLayout
Android:id="@+id/RL_MainMenu"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="1" Android:onClick="onDoNothing">
<ImageView
Android:id="@+id/ImageView01"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="4"
Android:src="@drawable/main_bg" Android:scaleType="centerCrop"/>
<ImageView
Android:id="@+id/Img_logo"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="4"
Android:scaleType="center"
Android:src="@drawable/logo_al" />
<LinearLayout
Android:id="@+id/LI_Menu"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_above="@+id/RL_ExtraOption"
Android:layout_alignTop="@+id/Img_logo"
Android:layout_margin="2dp"
Android:orientation="vertical" >
<ImageButton
Android:id="@+id/Img_Buyer"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_margin="1dp"
Android:layout_weight="1"
Android:background="@drawable/bt_blink"
Android:onClick="Nextclick"
Android:scaleType="fitCenter"
Android:soundEffectsEnabled="true"
Android:src="@drawable/buyer_icon" />
<ImageButton
Android:id="@+id/Img_Seller"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_margin="1dp"
Android:layout_weight="1"
Android:background="@drawable/bt_blink"
Android:onClick="Nextclick"
Android:scaleType="fitCenter"
Android:src="@drawable/seller_icon" />
<ImageButton
Android:id="@+id/Img_Lender"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_margin="1dp"
Android:layout_weight="1"
Android:background="@drawable/bt_blink"
Android:onClick="Nextclick"
Android:scaleType="fitCenter"
Android:src="@drawable/lender_icon" />
<ImageButton
Android:id="@+id/Img_myTitleRep"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_margin="1dp"
Android:layout_weight="1"
Android:background="@drawable/bt_blink"
Android:onClick="Nextclick"
Android:scaleType="fitCenter"
Android:src="@drawable/my_title_rep_icon_al" />
<ImageButton
Android:id="@+id/Img_Setup"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_margin="1dp"
Android:layout_weight="1"
Android:background="@drawable/bt_blink"
Android:onClick="Nextclick"
Android:scaleType="fitCenter"
Android:src="@drawable/setup_icon" />
</LinearLayout>
<RelativeLayout
Android:id="@+id/RL_ExtraOption"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_alignParentBottom="true"
Android:background="@drawable/main_bottom_bg" >
<TextView
Android:id="@+id/txt_RepName"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_centerVertical="true"
Android:layout_marginLeft="10dp"
Android:textColor="@color/white"
Android:textSize="@dimen/font_size" />
<TableRow
Android:id="@+id/TR_ContactRep"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignParentRight="true"
Android:layout_centerVertical="true"
Android:gravity="center" >
<Button
Android:id="@+id/Btn_ContactRep"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginRight="3dp"
Android:background="@drawable/contact_rep_blink"
Android:onClick="ContactRep_Click" />
<Button
Android:id="@+id/Btn_MoreOption"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginRight="5dp"
Android:background="@drawable/main_more_blink"
Android:onClick="onMoreClick" />
</TableRow>
</RelativeLayout>
<LinearLayout
Android:id="@+id/ln_Mainmore"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="@drawable/dialog_bg" Android:layout_alignParentBottom="true" Android:visibility="gone">
<LinearLayout
Android:id="@+id/LinearLayout02"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_weight="3"
Android:orientation="vertical" >
</LinearLayout>
<TableLayout
Android:id="@+id/TableLayout01"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_weight="1"
Android:gravity="center" >
<TableRow
Android:id="@+id/TableRow04"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_margin="5dp"
Android:layout_marginTop="20dp"
Android:gravity="center" >
<Button
Android:id="@+id/Btn_Rate"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="1"
Android:background="@drawable/property_blue_blink"
Android:onClick="onRate"
Android:singleLine="true"
Android:text="Rate/Testimonial"
Android:textColor="@color/white"
Android:textSize="@dimen/font_size"
Android:textStyle="bold" />
</TableRow>
<TableRow
Android:id="@+id/TableRow01"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_margin="5dp"
Android:gravity="center" >
<Button
Android:id="@+id/btn_SubFeature"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="1"
Android:background="@drawable/property_blue_blink"
Android:onClick="onSubFeature"
Android:singleLine="true"
Android:text="Submit A Feature"
Android:textColor="@color/white"
Android:textSize="@dimen/font_size"
Android:textStyle="bold" />
</TableRow>
<TableRow
Android:id="@+id/TableRow03"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_margin="5dp"
Android:gravity="center" >
<Button
Android:id="@+id/Btn_ReferFrnd"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="1"
Android:background="@drawable/property_blue_blink"
Android:onClick="onReferAFrnd"
Android:text="Refer A Friend"
Android:textColor="@color/white"
Android:textSize="@dimen/font_size"
Android:textStyle="bold" />
</TableRow>
<TableRow
Android:id="@+id/TableRow02"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_margin="5dp"
Android:gravity="center" >
<Button
Android:id="@+id/Btn_cancel"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_weight="1"
Android:background="@drawable/property_cancel_blink"
Android:onClick="onClose"
Android:text="Cancel"
Android:textColor="@color/black"
Android:textSize="@dimen/font_size"
Android:textStyle="bold" />
</TableRow>
</TableLayout>
<LinearLayout
Android:id="@+id/linearLayout2"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_weight="3"
Android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
</RelativeLayout>
Je suppose que le problème n'est pas dans votre mise en page; le problème est ailleurs dans votre code. Et vous avez probablement une fuite de contexte quelque part.
Une autre raison probable est que vous devez créer plusieurs objets volumineux lors de l'analyse de votre XML (comme vous l'avez mentionné, cela se produit la première fois lorsque vous analysez XML). Bien que Java a une approche de collecte automatique des ordures, mais vous ne pouvez toujours pas vous y fier complètement. C'est une bonne pratique de annuler votre instance de collection ou effacer le contenu de vos objets lorsque vous ne le faites pas ' je n'en ai plus besoin.
Mais j'ai quand même préparé une liste de points importants dont vous devez vous souvenir lorsque vous traitez avec des bitmaps sur Android.
1) Vous pouvez appeler recycle sur chaque bitmap et les mettre à null. (bitmap.recycle()
libérera toute la mémoire utilisée par ce bitmap, mais il n'annule pas l'objet bitmap).
2) Vous pouvez également dissocier le drawables
associé aux présentations lorsqu'une activité est détruite. Essayez le code ci-dessous et regardez également ce lien link .
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
// Call this method from onDestroy()
void onDestroy() {
super.onDestroy();
unbindDrawables(findViewById(R.id.RootView));
System.gc();
}
3) Vous pouvez convertir votre hashmaps
en WeakHashmaps
, afin que sa mémoire soit libérée lorsque le système manque de mémoire.
4) Vous pouvez mettre à l'échelle/redimensionner tous vos bitmaps. Pour mettre à l'échelle des bitmaps, vous pouvez essayer quelque chose comme ceci:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap preview_bitmap=BitmapFactory.decodeStream(is, null, options);
Cette option inSampleSize réduit la consommation de mémoire.
Voici une méthode complète. Il lit d'abord la taille de l'image sans décoder le contenu lui-même. Ensuite, il trouve la meilleure valeur inSampleSize; ça devrait être une puissance de 2. Et enfin l'image est décodée.
// Decodes image and scales it to reduce memory consumption
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;
}
Jetez un oeil à ce lien. .
5) Vous pouvez remplacer la méthode onLowMemory()
dans une activité qui reçoit un appel lorsque le système entier manque de mémoire. Vous pouvez y libérer quelques ressources.
6) Vous pouvez créer vos objets SoftReference
ou Weakreference
, afin qu'ils soient libérés dans une condition de mémoire insuffisante.
Une fuite de mémoire très courante que j'ai observée est due à l'implémentation de classes internes et à l'implémentation de Handler
dans Activity
. Ce lien parle de la même chose plus en détail .
J'espère que cela aide à éliminer votre problème.
Il s'agit d'un problème typique lors de l'utilisation de ImageView
d'Android avec de grandes images sur des appareils plus anciens (même si la taille du fichier n'est que de plusieurs Ko). La bibliothèque graphique native appelée skia qui est utilisée pour décoder l'image alloue la mémoire native en fonction des dimensions de l'image, de sorte que la taille du fichier n'influence pas cela directement.
Même si vous omettez l'attribut src
- dans la définition de disposition XML pour charger vous-même l'image dans votre méthode onCreate()
, la même erreur sera déclenchée. La seule façon de contourner ce problème est d'utiliser un inSampleSize
dans BitmapFactory.decodeStream
Pour effectuer un sous-échantillonnage directement pendant le décodage (voir Problème de mémoire insuffisante lors du chargement d'une image dans un objet Bitmap par exemple). Cela pose en soi la question de savoir comment déterminer ce facteur d'échelle.
La meilleure solution que j'ai trouvée lors de la manipulation d'images volumineuses est de remplacer le ImageView
par un WebView
et de charger un peu de code HTML comme ceci:
webView.loadUrl("file:///Android_res/raw/background.html");
où le contenu de raw/background.html
pourrait ressembler à ceci:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<style type="text/css">
body {
margin: 0;
}
img {
width: 100%;
height: auto;
display: block;
}
</style>
</head>
<body>
<img src="file:///Android_res/drawable/background.png" />
</body>
Le moteur WebKit utilisé dans WebView effectue le chargement d'image d'une manière beaucoup plus efficace, de sorte que ces erreurs d'allocation de mémoire devraient disparaître.
Vous pouvez même utiliser différentes images pour le portrait et le paysage en les mettant dans drawable-port
Et drawable-land
. Mais vous devez ensuite appeler clearCache(false)
sur l'instance WebView dans votre méthode onDestroy()
car sinon l'image mise en cache lors du premier chargement sera toujours utilisée (la désactivation de la mise en cache sur l'instance WebView ne fonctionne pas ).
Après avoir passé beaucoup de temps sur ce problème, j'ai trouvé la solution! Il vous suffit de demander plus de mémoire. Placez ce code dans votre manifeste Android manifeste sous:
<application>:
Mettre:
Android:largeHeap="true"
Fonctionne très bien pour moi! Veuillez noter que cette solution ne fonctionne que sur l'API 11 et les versions ultérieures.
Plus d'informations ici.
en plus de ce que les gens ont écrit ici, je suggère de regarder cette vidéo de google, qui pointe vers certains problèmes de mémoire courants et comment trouver la cause de votre problème de mémoire:
De nombreux appareils ont une mémoire très limitée et restreinte disponible pour chaque appareil. De nombreux appareils plus anciens allouent 16 Mo de mémoire à votre application, tandis que certains appareils plus modernes peuvent allouer 24 Mo ou même 32 Mo (j'ai vu un appareil avec seulement 14 Mo).
Chaque fois que vous chargez autant d'images en mémoire, cet espace se remplit très rapidement, provoquant le déclenchement de OutOfMemoryError. Pour surmonter ce problème, vous devez (comme les réponses précédentes l'ont dit) réduire les images en vignettes et ne conserver que les vignettes dans la mémoire de l'appareil (encombrement mémoire réduit) et enregistrer les images sur SDCARD.
Vous pouvez voir la quantité de mémoire utilisée par votre programme à partir de la disposition DDMS dans Eclipse. Je crois que vous pouvez également remplacer la classe Application pour écouter une fonction d'avertissement "Mémoire faible".
Lorsque vous lisez le bitmap via BitmapFactory, définissez le paramètre BitmapFactory.Option inScaled sur 2 ou 4 (ou tout ce qui vous convient) pour créer une image plus petite et moins gourmande en mémoire.
Généralement, il n'y a qu'une seule solution: utiliser des images plus petites. S'il n'y a pas de code, il est difficile de dire ce qui ne va pas. Vous pouvez essayer de réduire la taille de l'image.
J'ai eu le même problème avant et je déboguais sur S4 Android 4.3. La solution était: Copiez les images du dossier mdpi vers le dossier hdpi (elles sont donc maintenant sur les deux dossiers) )
Je sais bizarre! mais cela a résolu mon problème.
Il semble que votre image soit de grande taille, donc vous pouvez décoder votre image et utiliser Android: largeHeap = "true". dans le manifeste du tag d'application
vous avez peut-être passé par toutes les solutions ci-dessus, mais essayez toujours. J'étais perdue à trouver une solution jusqu'à ce que je la fasse fonctionner. Cela pourrait fonctionner de nuit pour votre cas (Excusez-moi dans ce cas).
myIntent.setFlags (Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_TASK); myIntent.setFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
placez-les avant d'appeler votre activité.