InflateException: Binary XML file line #21: Error inflating class <unknown> caused by OutOfMemoryError

2.8k views Asked by At

Please have a look at the following code

activity_game.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/ecran"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.florian.altarconquest.View.EcranJeu">
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:background="@drawable/blue_flag_icon" />

        <TextView
            android:id="@+id/compteurDrapeauBleu"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="0"
            android:textColor="#0000CD"
            android:textSize="50dp"
            android:textStyle="bold" />

        <ImageView
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:background="@drawable/red_flag_icon" />

        <TextView
            android:id="@+id/compteurDrapeauRouge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="20"
            android:text="0"
            android:textSize="50dp"
            android:textStyle="bold"
            android:textColor="#FF0000"/>
        <ImageView
            android:id="@+id/attackToken"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_weight="1"
            android:background="@drawable/jeton_noir_et_tour"
            />
        <ImageView
            android:id="@+id/defencetoken"
            android:background="@drawable/jeton_blanc_et_tour"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_weight="1"
            />

    </LinearLayout>
    <Button
        android:id="@+id/flagButton"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="100dp"
        android:background="@drawable/flag_icon" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="50dp"
        android:orientation="horizontal">
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="30"
            android:orientation="horizontal"></LinearLayout>
        <Button
            android:id="@+id/qrCodeButton"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:background="@drawable/qr_code_icon" />
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="30"
            android:orientation="horizontal">
        </LinearLayout>
        <Button
            android:id="@+id/mapButton"
            android:layout_width="50dp"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:background="@drawable/map_icon" />
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="30"
            android:orientation="horizontal"></LinearLayout>
    </LinearLayout>
    <Button
        android:id="@+id/unactiveTreeButton"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:background="@drawable/unactive_tree" />
    <Button
        android:id="@+id/treeButton"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:background="@drawable/tree_icon" />
</RelativeLayout>
<ImageView
    android:id="@+id/economyEnergie"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

EcranJeu.java

public class EcranJeu extends FragmentActivity implements OnMapReadyCallback {

public GoogleMap mMap;
public EcomieEnergie economieEnergie;
private Button mapButton, flagButton, qrCodeButton, treeButton, unactiveTreeButton;
private static ImageView attackToken;
private static ImageView defenceToken;
private Boolean attackTokenAvailable = true, defenseTokenAvailable = true;
private RelativeLayout ecran;
private ArrayList<Button> boutonsDeployables;
public ImageView imageEconomie;

private String pseudo;
private String gameId;
private Game game;

private final int REQUEST_CODE = 128;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_game);

    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

    imageEconomie = (ImageView) findViewById(R.id.economyEnergie);

    boutonsDeployables = new ArrayList<Button>();


    Bundle bundle = getIntent().getExtras();
    game = bundle.getParcelable("game");

    if (savedInstanceState == null) {
        Bundle extras = getIntent().getExtras();
        if(extras == null) {
            gameId = null;
        } else {
            gameId = extras.getString("STRING_GAMEID");
        }
    } else {
        gameId = (String) savedInstanceState.getSerializable("STRING_GAMEID");
    }

    boutonsDeployables = new ArrayList<Button>();

    attackToken = (ImageView) findViewById(R.id.attackToken);
    defenceToken = (ImageView) findViewById(R.id.defencetoken);


    mapButton = (Button) findViewById(R.id.mapButton);
    boutonsDeployables.add(mapButton);
    mapButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // Ouvre la grande map avec l'altar
            // A compléter
        }
    });

    flagButton = (Button) findViewById(R.id.flagButton);
    boutonsDeployables.add(flagButton);
    flagButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // Code pour intercepter un drapeau ennemi
            // A compléter
        }
    });

    qrCodeButton = (Button) findViewById(R.id.qrCodeButton);
    boutonsDeployables.add(qrCodeButton);
    qrCodeButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ouvrirScanQrCode();
        }
    });

    for(Button leBouton: boutonsDeployables){
        leBouton.setVisibility(View.INVISIBLE);
        leBouton.setClickable(false);
    }

    treeButton = (Button) findViewById(R.id.treeButton);
    treeButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // On clique sur le bouton du milieu, affichage
            // des trois autres boutons
            for(Button leBouton: boutonsDeployables){
                leBouton.setVisibility(View.VISIBLE);
                leBouton.setClickable(true);

                treeButton.setVisibility(View.INVISIBLE);
            }
        }
    });


    economieEnergie = new EcomieEnergie(this);
    economieEnergie.start();


    Timer timer = null;
    TimerTask timerTask = new TimerTask() {
        @Override
        public void run() {
            ServerReceptionCoordinates src = new ServerReceptionCoordinates(game);
            src.execute();
        }
    };

    timer.schedule(timerTask, 0, 1000);

}

public void onWindowFocusChanged(boolean hasFocus) {

    super.onWindowFocusChanged(hasFocus);

    unactiveTreeButton = (Button)findViewById(R.id.unactiveTreeButton);

    unactiveTreeButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(qrCodeButton.isClickable()){
                for(Button leBouton: boutonsDeployables){
                    leBouton.setVisibility(View.INVISIBLE);
                    leBouton.setClickable(false);
                }

                treeButton.setVisibility(View.VISIBLE);
                treeButton.setClickable(true);
            }
        }
    });


}

public void ouvrirScanQrCode() {
    Intent intent = new Intent(this, EcranScanQrCode.class);
    startActivity(intent);
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    double depInfoLat = 48.08574927627401;
    double depInfoLng = -0.7584989108085632;

    // Initialisation de la position de départ de la caméra
    LatLng startCameraPosition = new LatLng(depInfoLat, depInfoLng);
    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(startCameraPosition, 17.0f));


    GroundOverlayOptions groundOverlayOptions = new GroundOverlayOptions();
    BitmapDescriptor image = BitmapDescriptorFactory.fromResource(R.drawable.echologia_map);

    groundOverlayOptions.image(image).position(new LatLng(48.10872932860948, -0.7233687971115112), 380f).transparency(0.2f);
    GroundOverlay imageOverlay = mMap.addGroundOverlay(groundOverlayOptions);


    demanderPermissionGps();
    launchServerRequest(game);

}

public void launchServerRequest(Game game){
    Log.i("Début", "requete serveur flags");
    ServerReceptionFlagsPositions srf = new ServerReceptionFlagsPositions(game, this);
    srf.execute();
}

public void demanderPermissionGps(){
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        mMap.setMyLocationEnabled(true);
    } else {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case REQUEST_CODE: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    mMap.setMyLocationEnabled(true);
                }

            } else {
                demanderPermissionGps();
            }
            return;
        }

    }
}


public static void setDefencetoken(boolean defenceTokenAvailable){
    if(defenceTokenAvailable){
        defenceToken.setImageResource(R.drawable.jeton_blanc);
    }
    else{
        defenceToken.setImageResource(R.drawable.jeton_blanc_et_tour);
    }

}

public static void setAttackToken(boolean attackTokenAvailable){
    if(attackTokenAvailable){
        attackToken.setImageResource(R.drawable.jeton_noir);
    }
    else{
        attackToken.setImageResource(R.drawable.jeton_noir_et_tour);
    }

}

}

When I launch the app and I change the activity to EcranJeu, it will crash. I know it is due to an image but I definitely can't find the right one.

12-12 22:00:59.580 24658-24658/com.example.florian.altarconquest E/AndroidRuntime: FATAL EXCEPTION: main
                                                                               Process: com.example.florian.altarconquest, PID: 24658
                                                                               java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.florian.altarconquest/com.example.florian.altarconquest.View.EcranJeu}: android.view.InflateException: Binary XML file line #21: Binary XML file line #21: Error inflating class <unknown>
                                                                                   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2464)
                                                                                   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2524)
                                                                                   at android.app.ActivityThread.access$900(ActivityThread.java:154)
                                                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1391)
                                                                                   at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                   at android.os.Looper.loop(Looper.java:234)
                                                                                   at android.app.ActivityThread.main(ActivityThread.java:5526)
                                                                                   at java.lang.reflect.Method.invoke(Native Method)
                                                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                                                Caused by: android.view.InflateException: Binary XML file line #21: Binary XML file line #21: Error inflating class <unknown>
                                                                                   at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
                                                                                   at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
                                                                                   at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
                                                                                   at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:400)
                                                                                   at android.app.Activity.setContentView(Activity.java:2177)
                                                                                   at com.example.florian.altarconquest.View.EcranJeu.onCreate(EcranJeu.java:60)
                                                                                   at android.app.Activity.performCreate(Activity.java:6285)
                                                                                   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
                                                                                   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417)
                                                                                   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2524) 
                                                                                   at android.app.ActivityThread.access$900(ActivityThread.java:154) 
                                                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1391) 
                                                                                   at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                   at android.os.Looper.loop(Looper.java:234) 
                                                                                   at android.app.ActivityThread.main(ActivityThread.java:5526) 
                                                                                   at java.lang.reflect.Method.invoke(Native Method) 
                                                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
                                                                                                                                                                                                                                                Caused by: java.lang.OutOfMemoryError: Failed to allocate a 9437196 byte allocation with 5482336 free bytes and 5MB until OOM
                                                                                   at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
                                                                                   at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
                                                                                   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
                                                                                   at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
                                                                                   at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1080)
                                                                                   at android.content.res.Resources.loadDrawableForCookie(Resources.java:2647)
                                                                                   at android.content.res.Resources.loadDrawable(Resources.java:2552)
                                                                                   at android.content.res.TypedArray.getDrawable(TypedArray.java:870)
                                                                                   at android.view.View.<init>(View.java:4030)
                                                                                   at android.widget.ImageView.<init>(ImageView.java:145)
                                                                                   at android.widget.ImageView.<init>(ImageView.java:140)
                                                                                   at android.widget.ImageView.<init>(ImageView.java:136)
                                                                                   at java.lang.reflect.Constructor.newInstance(Native Method) 
                                                                                   at android.view.LayoutInflater.createView(LayoutInflater.java:619) 
                                                                                   at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58) 
                                                                                   at android.view.LayoutInflater.onCreateView(LayoutInflater.java:694) 
                                                                                   at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:762) 
                                                                                   at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) 
                                                                                   at android.view.LayoutInflater.rInflate(LayoutInflater.java:835) 
                                                                                   at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
                                                                                   at android.view.LayoutInflater.rInflate(LayoutInflater.java:838) 
                                                                                   at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
                                                                                   at android.view.LayoutInflater.rInflate(LayoutInflater.java:838) 
                                                                                   at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) 
                                                                                   at android.view.LayoutInflater.inflate(LayoutInflater.java:515) 
                                                                                   at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
                                                                                   at android.view.LayoutInflater.inflate(LayoutInflater.java:374) 
                                                                                   at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:400) 
                                                                                   at android.app.Activity.setContentView(Activity.java:2177) 
                                                                                   at com.example.florian.altarconquest.View.EcranJeu.onCreate(EcranJeu.java:60) 
                                                                                   at android.app.Activity.performCreate(Activity.java:6285) 
                                                                                   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108) 
                                                                                   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417) 
                                                                                   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2524) 
                                                                                   at android.app.ActivityThread.access$900(ActivityThread.java:154) 
                                                                                   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1391) 
                                                                                   at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                   at android.os.Looper.loop(Looper.java:234) 
                                                                                   at android.app.ActivityThread.main(ActivityThread.java:5526) 
                                                                                   at java.lang.reflect.Method.invoke(Native Method) 
                                                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

The error target this line :

setContentView(R.layout.activity_game);
1

There are 1 answers

2
CommonsWare On BEST ANSWER

You have a bunch of ImageView widgets on which you are using android:background rather than android:src. It is unclear why you are doing this.

Regardless, on one of those, you are attempting to load a drawable resource that, when decoded, would take up 9437196 bytes of heap space. That is the equivalent of a 1536x1536 image. This is much too large.

So, switch to android:src and use much lower-resolution bitmaps. The size of the bitmaps on disk is irrelevant.

Also, if you happened to put these images in res/drawable/, bear in mind that this is synonymous with res/drawable-mdpi/ and indicates that your images should be upscaled for higher-density screens.