How to decrease memory consumption in Android App

1

Hello friends, I have a question for you. I have an android app which basically are two activities the main_activity and a details activity . The first has a recyclerView with elements and when I touch one I enter the activity details the issue is that when I enter the activity_detalles the consumption of my app is doubled and goes from 65 mb to 125mb , when leaving this activity, this memory consumption is maintained, which means that users with a low-end telephone have failures.

How can I release memory when leaving the activity details? for this, here I put my activity details.

    public class DetailActivity extends AppCompatActivity {

    public static final String EXTRA_POSITION = "position";
    RatingBar ratingBar;



    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);

       // MobileAds.initialize(getApplicationContext(), getString(R.string.llavedeapp));
        setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        // Set Collapsing Toolbar layout to the screen
        final CollapsingToolbarLayout collapsingToolbar =
                (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
        // Set title of Detail page
        // collapsingToolbar.setTitle(getString(R.string.item_title));



        ratingBar = (RatingBar) findViewById(R.id.ratingBarId);
        ratingBar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
            @Override
            public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
                Toast.makeText(getApplicationContext(), getString(R.string.calificado) + " " + ratingBar.getRating() + " " + getString(R.string.estrellas), Toast.LENGTH_SHORT).show();
            }
        });


        int postion = getIntent().getIntExtra(EXTRA_POSITION, 0);
        Resources resources = getResources();
        String[] places = resources.getStringArray(R.array.nombre_coctel);
        collapsingToolbar.setTitle(places[postion % places.length]);

        String[] placeDetails = resources.getStringArray(R.array.coctel_ingredientes);
        TextView placeDetail = (TextView) findViewById(R.id.place_detail);
        placeDetail.setText(placeDetails[postion % placeDetails.length]);

        String[] placeLocations = resources.getStringArray(R.array.coctel_preparacion);
        TextView placeLocation = (TextView) findViewById(R.id.place_location);
        placeLocation.setText(placeLocations[postion % placeLocations.length]);

        String[] acercaDelCoctel = resources.getStringArray(R.array.coctel_descripcion);
        TextView acercaCoctel = (TextView) findViewById(R.id.acerca_del_coctel);
        acercaCoctel.setText(acercaDelCoctel[postion % acercaDelCoctel.length]);

        final TypedArray placePictures = resources.obtainTypedArray(R.array.places_picture);
        ImageView placePicutre = (ImageView) findViewById(R.id.image);
        placePicutre.setImageDrawable(placePictures.getDrawable(postion % placePictures.length()));

        TextView textHistoriaCoctel = (TextView) findViewById(R.id.TextHistoria);
        String[] historiaDelCoctel = resources.getStringArray(R.array.historia_coctel);
        TextView historiaCoctel = (TextView) findViewById(R.id.historia_coctel);

        //Verifico que el cóctel tenga una historia en el el array de historia
        //de lo contrario desaparezco las vistas de la pantalla
        if ((historiaDelCoctel[postion]).isEmpty()) {
            textHistoriaCoctel.setVisibility(View.GONE);
            historiaCoctel.setVisibility(View.GONE);
        } else {
            textHistoriaCoctel.setVisibility(View.VISIBLE);
            historiaCoctel.setVisibility(View.VISIBLE);
            historiaCoctel.setText(historiaDelCoctel[postion % historiaDelCoctel.length]);
        }
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                MobileAds.initialize(getApplicationContext(), "ca-app-pub-8600901870293215/4069468888");
                AdView mAdView = (AdView) findViewById(R.id.adView);
                AdRequest adRequest = new AdRequest.Builder().build();
                mAdView.loadAd(adRequest);

                placePictures.recycle();


                ImageButton favoriteImageButton = (ImageButton) findViewById(R.id.share_button);
                favoriteImageButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent sendIntent = new Intent();
                        sendIntent.setAction(Intent.ACTION_SEND);
                        sendIntent.putExtra(Intent.EXTRA_TEXT, conformarCuerpoEmail());
                        sendIntent.setType("text/plain");
                        startActivity(sendIntent);
                    }
                });

                ImageButton shareImageButton = (ImageButton) findViewById(R.id.email_button);
                shareImageButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        sendEmail();
                    }

                });
            }
        });


    }

    /* Se crea un hilo al llamar el método @sendEmail lo que hace que la app trabaje mejore el rendimiento en
       * telefonos de baja gama.*/
    public void sendEmail() {
        new Thread(new Runnable() {
            public void run() {
                composeEmail("[email protected]", getString(R.string.comohacer), conformarCuerpoEmail());
            }
        }).start();
    }

    /*El método @conformarCuerpoEmail es el encargado de realizar el String correspondiente al cuerpo del mensaje
    * en el correo*/
    public String conformarCuerpoEmail() {

        int posicion = getIntent().getIntExtra(EXTRA_POSITION, 0);
        Resources resources = getResources();

        //Accediendo al nombre del  Cocktel
        String[] places = resources.getStringArray(R.array.nombre_coctel);
        String nombreTrago = places[posicion];

        //Accediendo al arreglo de Descripciones
        String[] place_desc = resources.getStringArray(R.array.coctel_descripcion);
        String descripcionTrago = place_desc[posicion];

        //Accediendo al arreglo de Ingredientes
        String[] placeDetails = resources.getStringArray(R.array.coctel_ingredientes);
        String ingredientesTrago = placeDetails[posicion];

        String[] placeLocations = resources.getStringArray(R.array.coctel_preparacion);
        String preparacionTrago = placeLocations[posicion];
        String cuerpoEmail;
        cuerpoEmail = "" + getString(R.string.nombre_trago) + "" + nombreTrago + "" + "\n"
                + getString(R.string.item_desc) + "\n" + " " + descripcionTrago + "\n"
                + " " + getString(R.string.ingredientes) + "\n" + " " + ingredientesTrago + "\n"
                + " " + getString(R.string.preparacion) + "\n" + " " + preparacionTrago;
        //Se devuelve el Cuerpo del mensaje que será enviado por correo
        return cuerpoEmail;
    }

    @Override
    protected void onPostResume() {
        super.onPostResume();
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    /* El método @composeEmail es el que conforma el correo lanazando un Intent*/
    public void composeEmail(String addresses, String subject, String body) {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setData(Uri.parse("mailto:")); // only email apps should handle this
        intent.setType("text/html");
        intent.putExtra(Intent.EXTRA_EMAIL, addresses);
        intent.putExtra(Intent.EXTRA_SUBJECT, subject);
        intent.putExtra(Intent.EXTRA_TEXT, body);
        // Uri.parse("file://"+ Environment.getDataDirectory());
        startActivity(Intent.createChooser(intent, "Send Email"));
    }


}
    
asked by Yasnier Perdigon Lorenzo 16.06.2017 в 18:37
source

1 answer

1

I notice that you use a ImageView , generally the main problem are images, which we must delete your reference or images which are not optimized and when loaded in the application cause a high memory consumption.

I suggest you define the ImageView variable in the class:

private ImageView placePicutre;

implement the onDestroy() method where you would assign a null value to the content of ImageView :

@Override
protected void onDestroy() {
    super.onDestroy();

    placePicutreimgView.setImageDrawable(null);

}

Review again and comment on results.

To detect the problem I advise you to read How to scan the used RAM

Open the Android Monitor go to Monitors , browse your application and then download the file by clicking the "Dump Java Heap" button.

  
  • At the top of the Memory monitor, click Dump Java Heap. Android Studio creates a heap summary file with the name of   application-id_yyyy.mm.dd_hh.mm.hprof file, open the file in   Android Studio and add the file to the Heap Snapshot list of the   Captures tab.
  •   

      
  • On the Captures tab, right-click on the file and select Export to standard .hprof.
  •   

    Having the .hprof file, you can use Memory Analyzer

    to detect "suspicious" leaks from memory:

    I advise you to review this question:

    good Resolution of an image causes "OutOfMemoryError"

        
    answered by 16.06.2017 в 22:15