How to free Memory in my android application

1

Good days

I'm already in the process of testing my android application, and I have a question what happens is that being doing several movements, the app freezes and gets a little slow, what I see is by memory detail of my app, is not releasing it, someone could tell me how the memory is released in an android app.

Thank you.

As I told you, the problem I have in my last screen is where the user has to generate charges .. right now I have already put a method to delete the cache of my application ... I leave the code of the activity where I have the problem and the screen ...

Activity detail

public class Detail_Client extends AppCompatActivity {

// Controls     public Button pay;     public Button Pagoc;

//Dialogos
ProgressDialog dialog;
AlertDialog alert = null;

//Array Detalle
ListView list;
ArrayList<DetalleCxP> DetalleArrayList = new ArrayList<DetalleCxP>();
MyArrayAdapter adaptador;

CXCPSaldoClienteProveedor O_Cliente;
DetalleMenu O_DetalleMenu;
Integer I_FormaPago=0;


//Manejo de Intent
public Bundle extras;
public Intent intent;
public String UsuarioCap;

//Ubicacion GPS
LocationManager locManager;
LocationListener locListener;


final Context context = this;
public String obser;
private static final String TAG = "mx.com.oncontrol.oncontrolmovile";

//Forma de Pago
public TextView formap;

//Array Forma de Pago
ArrayList<FormaPago> PagoArrayList = new ArrayList<FormaPago>();


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_detalle__cliente);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    //Manejo de Intent
    extras = getIntent().getExtras();
    UsuarioCap = extras.getString("UsuarioCaptura2");
    intent = getIntent();
    O_DetalleMenu=(DetalleMenu) intent.getSerializableExtra("O_DetalleMenu");
    intent=getIntent();
    O_Cliente=(CXCPSaldoClienteProveedor) intent.getSerializableExtra("O_Cliente");
    setTitle(O_Cliente.getClienteDescripcion());

    //codigo listview
    list=(ListView)this.findViewById(R.id.listDeta);
    AsyncCallWSDetalle task = new AsyncCallWSDetalle();
    //Call execute
    task.execute();
    comenzarLocalizacion();

   pagar = (Button)this.findViewById(R.id.btnpago);
    pagar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v)
        {
            AlertDialog.Builder alert = new AlertDialog.Builder(Detalle_Cliente.this);
            alert.setMessage("¿Estas Seguro de Aplicar el Abono?");
            alert.setTitle("Confirmacion");

            alert.setPositiveButton("Aceptar", new DialogInterface.OnClickListener()  {
                public void onClick(DialogInterface dialog, int id) {
                    I_FormaPago=((FormaPago)((Spinner)findViewById(R.id.menu_spinner1)).getSelectedItem()).getId();

                    comenzarLocalizacion();
                    AsyncGrabarCXCP task = new AsyncGrabarCXCP();


                    //Call execute
                    task.execute();
                }
            });
            alert.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
                }
            });
            alert.show();
        }
    });


    Pagoc = (Button)this.findViewById(R.id.btn_pagoceros);
    Pagoc.setOnClickListener(new View.OnClickListener() {
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        @Override
        public void onClick(View v)
        {
            LayoutInflater li = LayoutInflater.from(context);
            View pron = li.inflate(R.layout.row_dialog, null);

            AlertDialog.Builder alert = new AlertDialog.Builder(context);
            alert.setTitle("Confirmacion de Pago en 0!");
            alert.setMessage("Favor Ingresa el Motivo Por el " +
                              "cual no se realizo el Pago");
            alert.setView(pron);
            final EditText observ = (EditText)pron.findViewById(R.id.edtobser);
            obser = observ.getText().toString();
            alert.setCancelable(false);
            alert.setPositiveButton("Aceptar", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                comenzarLocalizacion();
                AsyncGrabarCXCP task = new AsyncGrabarCXCP();
                obser = observ.getText().toString();
                //Call execute
                task.execute();
            }
        });
            alert.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                       dialog.cancel();
                }
            });
            alert.show();
        }
    });

}
//Codigo de Buscador en la parte del ActionBar
@Override
public boolean onCreateOptionsMenu(android.view.Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_detalle, menu);
    MenuItem item = menu.findItem(R.id.menu_spinner1);
    Spinner spinner = (Spinner) MenuItemCompat.getActionView(item);

    //Se manda a llamar el metodo del spinner
    AsyncForma task = new AsyncForma();
    //Call execute
    task.execute();
    return true;

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}



private void comenzarLocalizacion() {
    //Obtenemos una referencia al LocationManager
    locManager =
            (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    //Obtenemos la última posición conocida
    Location loc = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

    if(loc != null)
    {
        O_Cliente.setGPSLocation("http://maps.google.com/maps?q=" + String.valueOf(loc.getLatitude() + ",+" + String.valueOf(loc.getLongitude())));
    }


    //Nos registramos para recibir actualizaciones de la posición
    locListener = new LocationListener() {


        public void onLocationChanged(Location location) {
            if(location.getLatitude() != 0.0D && location.getLongitude() != 0.0D) {
                try {
                    Geocoder e = new Geocoder(Detalle_Cliente.this, Locale.getDefault());
                    List list = e.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
                    if(!list.isEmpty()) {
                        Address DirCalle = (Address)list.get(0);
                        //direccion.setText("Mi direccion es: \n" + DirCalle.getAddressLine(0));
                        O_Cliente.setGPSLocation2(DirCalle.getAddressLine(0));
                    }
                } catch (IOException var5) {
                    var5.printStackTrace();
                }
            }

        }

        public void onProviderDisabled(String provider) {
            //lblEstado.setText("Provider OFF");
        }

        public void onProviderEnabled(String provider) {
            //lblEstado.setText("Provider ON ");
        }

        public void onStatusChanged(String provider, int status, Bundle extras) {
            /*Log.i("", "Provider Status: " + status);
            lblEstado.setText("Provider Status: " + status);*/
        }
    };

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    }
    locManager.requestLocationUpdates(
            LocationManager.GPS_PROVIDER, 1000, 0, locListener);
}


private class AsyncCallWSDetalle extends AsyncTask<String, ArrayList, ArrayList> {


    @Override
    protected ArrayList doInBackground(String... params){
        DetalleArrayList=webService.DetalleCxP(O_Cliente.getCliente(), O_DetalleMenu.getDocumento());
        return null;

    }

    @Override
    //Make Progress Bar visible
    protected void onPreExecute() {

        dialog=new ProgressDialog(Detalle_Cliente.this);
        dialog.setIndeterminate(false);
        dialog.setMessage("Cargando Detalle...");
        dialog.setCancelable(false);
        dialog.show();

    }

    //Once WebService returns response
    @Override
    protected void onPostExecute(ArrayList arrayList) {
        super.onPostExecute(arrayList);
        if(DetalleArrayList.size()!=0){
            dialog.dismiss();

            adaptador= new MyArrayAdapter(Detalle_Cliente.this, DetalleArrayList);///* no se usa your_array_list

            list = (ListView) findViewById(R.id.listDeta);
            list.setAdapter(adaptador);
            adaptador.notifyDataSetChanged();


        }else{
            dialog.dismiss();
        }
    }
}




public class MyArrayAdapter extends ArrayAdapter<DetalleCxP> {


    public MyArrayAdapter(Context context, ArrayList<DetalleCxP> ArrayClientes) {
        super(context, 0, ArrayClientes);
    }

    public View getView(int position, View convertView, ViewGroup parent) {

        DetalleCxP O_DetalleCxP = getItem(position);

        // Check if an existing view is being reused, otherwise inflate the view
        if (convertView == null)
        {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_detalle, parent, false);
            //Abono = (EditText) convertView.findViewById(R.id.edt_abono);
            //attach the TextWatcher listener to the EditText
            ((EditText) convertView.findViewById(R.id.edt_abono)).addTextChangedListener(new TB_Abono_Watcher(convertView));
        }

        //Obteniendo instancias de los text views
        /*
        vencido = (TextView)convertView.findViewById(R.id.txtvencido);
        saldo = (TextView)convertView.findViewById(R.id.txttotal);
        Abono = (EditText) convertView.findViewById(R.id.edt_abono);
        total = (TextView)convertView.findViewById(R.id.total);

* /

        DecimalFormat numberFormat  = new DecimalFormat("###,##0.00");

        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");



        ((TextView)convertView.findViewById(R.id.txtFecha)).setText(dateFormat.format(O_DetalleCxP.getFecha()));


        ((TextView)convertView.findViewById(R.id.txtFolio)).setText(O_DetalleCxP.getFolio());

        ((EditText) convertView.findViewById(R.id.edt_abono)).setTag(O_DetalleCxP);
        if (O_DetalleCxP.TotalAplicado>0)
        {
            ((EditText) convertView.findViewById(R.id.edt_abono)).setText(numberFormat.format(O_DetalleCxP.TotalAplicado));
        }
        else
        {
            ((EditText) convertView.findViewById(R.id.edt_abono)).setText("");
        }

        ((TextView)convertView.findViewById(R.id.total)).setText(numberFormat.format(O_DetalleCxP.getTotal()));
        ((TextView)convertView.findViewById(R.id.txttotal)).setText(numberFormat.format(O_DetalleCxP.getSaldo()));
        ((TextView)convertView.findViewById(R.id.txtvencido)).setText(numberFormat.format(O_DetalleCxP.getSaldoVencido()));




        //Devolver al ListView la fila creada
        return convertView;

    }
}



//Clase para Edittext
private class TB_Abono_Watcher implements TextWatcher{


   Button pagar =(Button)findViewById(R.id.btnpago);
    private View view;
    private TB_Abono_Watcher(View view) {
        this.view = view;
    }

    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }
    public void onTextChanged(CharSequence s, int start, int before, int count) {

        //do nothing
    }
    public void afterTextChanged(Editable s)
    {

        //Abono = (EditText)view.findViewById(R.id.edt_abono);
        DetalleCxP O_DetalleCxP = (DetalleCxP)((EditText)view.findViewById(R.id.edt_abono)).getTag();
        O_DetalleCxP.TotalAplicado=ONC_SYS.NullToZeroDouble(s.toString());

        Double Total=0.0;
        for(int i=0;i<DetalleArrayList.size();i++)
        {
            if (((DetalleCxP)DetalleArrayList.get(i)).TotalAplicado>0)
            {
                Total += ((DetalleCxP)DetalleArrayList.get(i)).TotalAplicado;
            }
        }
        DecimalFormat numberFormat  = new DecimalFormat("0.00");
        ((TextView)findViewById(R.id.txtTotal)).setText(numberFormat.format(Total));

        if (Total==0)
        {
            ((Button)findViewById(R.id.btn_pagoceros)).setEnabled(true);
            ((Button)findViewById(R.id.btnpago)).setEnabled(false);
        }
        else
        {
            ((Button)findViewById(R.id.btn_pagoceros)).setEnabled(false);
            ((Button)findViewById(R.id.btnpago)).setEnabled(true);
        }


        //Validacion que no te deje hacer un abono Mayo al saldo vencido
        if (O_DetalleCxP.getSaldo() < O_DetalleCxP.TotalAplicado)
        {
            Toast.makeText(getApplicationContext(),"No puedes Aplicar un Abono Mayor al SaldoVencido",Toast.LENGTH_SHORT).show();
            ((EditText)view.findViewById(R.id.edt_abono)).setText("");

        }
    }
}


//Medoto para Grabar datos

public class AsyncGrabarCXCP extends AsyncTask<Void,Integer,String>
{
    int Recurso;


    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        dialog=new ProgressDialog(Detalle_Cliente.this);
        dialog.setIndeterminate(false);
        dialog.setMessage("Procesando Datos...");
        dialog.setCancelable(false);
        dialog.show();
    }

    @Override
    protected String doInBackground(Void... params) {
        String Resultado="";

        Recurso=webService.ObtenerRecurso();
        String Folio = webService.ObtenerFolio(35);
        Date O_D = new Date();

        Double Factor=0.0, Importe=0.0, Descuento=0.0, SubTotal=0.0, Total=0.0, IVA=0.0,Retencion1=0.0,Retencion2=0.0,IEPS=0.0;

        Double DFactor=0.0;

        final int count = DetalleArrayList.size();

        for(int i=0;i<count;i++) {

            Factor=0.0;

            if (((DetalleCxP)DetalleArrayList.get(i)).TotalAplicado>0)
            {
                Factor = ((DetalleCxP)DetalleArrayList.get(i)).TotalAplicado / ((DetalleCxP)DetalleArrayList.get(i)).Total;

                Importe += ((DetalleCxP)DetalleArrayList.get(i)).Importe*Factor;
                Descuento += ((DetalleCxP)DetalleArrayList.get(i)).Descuento*Factor;
                SubTotal += ((DetalleCxP)DetalleArrayList.get(i)).SubTotal*Factor;
                IVA += ((DetalleCxP)DetalleArrayList.get(i)).IVA*Factor;
                Retencion1 += ((DetalleCxP)DetalleArrayList.get(i)).Retencion1*Factor;
                Retencion2 += ((DetalleCxP)DetalleArrayList.get(i)).Retencion2*Factor;
                IEPS += ((DetalleCxP)DetalleArrayList.get(i)).IEPS*Factor;
                Total += ((DetalleCxP)DetalleArrayList.get(i)).Total*Factor;
            }

        }


        Resultado = webService.LLenarEncabezadoCXCP(Recurso,
                "I",    //Accion I
                0,      //Id = 0
                O_Cliente.getEmpresa(), //Id de Empresa
                Folio,
                new Date(),
                O_Cliente.getCliente(),
                O_Cliente.getProveedor(),
                O_Cliente.getMoneda(),
                1.0,      //Tipo de Cambio por default 1
                0,      //Cuenta Bancaria
                UsuarioCap, //Usuario Captura
                I_FormaPago,          //Pago Forma
                Total,          //Saldo
                Importe,    //Importe
                0,          //Financiamiento
                Descuento,
                SubTotal,
                Retencion1,
                Retencion2,
                IEPS,
                IVA,
                0,          //ISH,
                Total,      //Total
                Total,      //totalaplicado,
                "A",        //status,
                "",         //usucariocancela,
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,   //Numero1...Numero10
                O_Cliente.getGPSLocation(), //Texto1
                O_Cliente.getGPSLocation2(),  //Texto2
                "","","","","","","","",                      //Texto1...Texto10
                new Date(),new Date(),new Date(),new Date(),new Date(),new Date(),  //Fecha1...Texto6
                obser,         //Observacion
                0,0,0,0,0,0,         //Catalogo1...Catalogo6
                "",         //ordencompra
                0,          //concepto
                "",         //observacioncancelacion
                0,          //origenventacompra,
                0           //origeninventario
        );
        if (Resultado.equals("OK"))
        {

            for(int i=0;i<DetalleArrayList.size();i++) {



                if (((DetalleCxP)DetalleArrayList.get(i)).TotalAplicado>0)
                {
                    DFactor = ((DetalleCxP)DetalleArrayList.get(i)).TotalAplicado / ((DetalleCxP)DetalleArrayList.get(i)).Total;


                    Resultado = webService.LLenarDetalleCXCP(Recurso,
                            "I", //Accion
                            0, //id
                            ((DetalleCxP)DetalleArrayList.get(i)).getId(),  //Origen
                            ((DetalleCxP)DetalleArrayList.get(i)).getDocumento(),  //OrigenDocumento
                            (Double)(((DetalleCxP)DetalleArrayList.get(i)).Importe*DFactor),   //Importe
                            (Double)0.0,  //Financiamiento
                            (Double)(((DetalleCxP)DetalleArrayList.get(i)).Descuento*DFactor), //Descuento
                            (Double)(((DetalleCxP)DetalleArrayList.get(i)).SubTotal*DFactor),   //Subtotal
                            (Double)(((DetalleCxP)DetalleArrayList.get(i)).Retencion1*DFactor), //Retencion1
                            (Double)(((DetalleCxP)DetalleArrayList.get(i)).Retencion2*DFactor),  //Retencion2
                            (Double)(((DetalleCxP)DetalleArrayList.get(i)).IEPS*DFactor),   //IEPS
                            (Double)(((DetalleCxP)DetalleArrayList.get(i)).IVA*DFactor), //IVA
                            (Double)0.0, //ISH
                            (Double)(((DetalleCxP)DetalleArrayList.get(i)).Total*DFactor),  //Total
                            ((DetalleCxP)DetalleArrayList.get(i)).getSaldo(),   //Saldo
                            "Android App"      //Referencia
                    );

                }

            }

        }


        if (Resultado.equals("OK"))

        {

            Resultado = webService.GrabarCxCP(Recurso,//Recurso
                    O_DetalleMenu.getModulo(),      //Modulo
                    O_DetalleMenu.getOperacion(),      //Operacion
                    O_DetalleMenu.getDocumento(),      //Documento
                    0,      //OrigenId
                    0);     //OrigenDocumento
        }

        return Resultado;
    }

    @Override
    protected void onPostExecute(String Resultado) {
        super.onPostExecute(Resultado);
        if (Resultado.equals("LA OPERACION FUE REALIZADA CON EXITO"))
        {
            dialog.dismiss();
            Toast.makeText(getApplicationContext(), "Datos Guardado Correctamente", Toast.LENGTH_SHORT).show();
            finish();
            }else{
                dialog.dismiss();
                Toast.makeText(getApplicationContext(), "Error en el Webservices" , Toast.LENGTH_LONG).show();
            }
    }
}

public DetalleCxP FindCXCPSaldoClienteProveedorById(int Id)
{
    for(int i=0;i<DetalleArrayList.size();i++)
    {
        if (DetalleArrayList.get(i).getId()==Id)
        {
            return DetalleArrayList.get(i);
        }
    }
    return null;
}


private class AsyncForma extends AsyncTask<String, ArrayList, ArrayList>
{

    @Override
    protected ArrayList doInBackground(String... params) {
        PagoArrayList=webService.FormaPago();
        return null;
    }

    @Override
    protected void onPostExecute(ArrayList arrayList) {
        super.onPostExecute(arrayList);

        if(PagoArrayList.size()!=0){

            Spinner spinner = (Spinner)findViewById(R.id.menu_spinner1);
            ArrayAdapter<FormaPago> adapter = new ArrayAdapter<FormaPago>(context, android.R.layout.simple_spinner_dropdown_item, PagoArrayList);
            spinner.setAdapter(adapter);

        }else{

        }
    }
}



@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@SuppressLint("LongLogTag")
@Override
protected void onDestroy() {
    super.onDestroy();
    Log.i(TAG, "onDestroy");
   DetalleArrayList = null;
    list = null;
    adaptador = null;
    O_DetalleMenu = null;
    extras = null;
    intent = null;
    UsuarioCap = null;
    obser = null;
    PagoArrayList = null;
    deleteCache(context);
    System.gc();
}


public static void deleteCache(Context context) {
    try {
        File dir = context.getCacheDir();
        deleteDir(dir);
    } catch (Exception e) {}
}

public static boolean deleteDir(File dir) {
    if (dir != null && dir.isDirectory()) {
        String[] children = dir.list();
        for (int i = 0; i < children.length; i++) {
            boolean success = deleteDir(new File(dir, children[i]));
            if (!success) {
                return false;
            }
        }
        return dir.delete();
    }
    else if(dir!= null && dir.isFile())
        return dir.delete();
    else {
        return false;
    }
}

}

    
asked by Hugo Rodriguez 25.05.2016 в 18:06
source

3 answers

2
  

the app freezes

Avoid carrying out processes that block the UI, if the main thread is blocked you can notice that your application "freezes" for a moment.

In this case you can use runOnUIThread or Asynctask

  

It gets a bit slow, what I see is by memory detail of my   app, is not releasing it

There are several causes of this, they could be objects that are not being deleted from memory by the Garbage collector as listeners or views etc. Regularly the main problem is the images or they are very large and when they are manipulated by the application they consume a large amount of memory, or they are not being eliminated from the containers, it must be ensured also to remove the reference of the images within imageView when we do not use them:

miImageView.setBackgroundDrawable(null) 

I recommend you review this answer: link

    
answered by 25.05.2016 в 19:09
0

Use the resource monitor where the Memory, CPU, Network graphs appear so you can really see where the charges occur, and you are discarding parts.

Also find information about possible Memory leacks link: Memory leak from bitmap

    
answered by 25.05.2016 в 20:37
0

Normally the low performance of our application is because everything is running on a single thread, the main thread. I recommend that you try to work with Threads to perform the functions separately.

You can rely on the resource monitor and define how to section the load of the activity.

You can support yourself with the following tutorial: Threads and Processes (Developers)

Also always try the final device, forget the emulators, just as advice.

Good luck! : D

    
answered by 26.05.2016 в 17:08