Domanda

mi sono bloccato con una perdita di memoria che non riesco a risolvere. Ho identificato in cui si verifica, utilizzando il MemoryAnalizer ma invano fatica a sbarazzarsi di esso. Ecco il codice:

public class MyActivity extends Activity implements SurfaceHolder.Callback {
 ...

Camera.PictureCallback mPictureCallbackJpeg = new Camera.PictureCallback() {
    public void onPictureTaken(byte[] data, Camera c) {
        try  {
            // log the action
            Log.e(getClass().getSimpleName(), "PICTURE CALLBACK JPEG: data.length = " + data);

            // Show the ProgressDialog on this thread 
            pd = ProgressDialog.show(MyActivity.this, "", "Préparation", true, false); 

            // Start a new thread that will manage the capture 
            new ManageCaptureTask().execute(data, c); 
        }
        catch(Exception e){
            AlertDialog.Builder dialog = new AlertDialog.Builder(MyActivity.this);
            ...
            dialog.create().show();
        }
    }

    class ManageCaptureTask extends AsyncTask<Object, Void, Boolean> { 
        protected Boolean doInBackground(Object... args) {
            Boolean isSuccess = false;

            // initialize the bitmap before the capture
            ((myApp) getApplication()).setBitmapX(null);
            try{

                // Check if it is a real device or an emulator
                TelephonyManager telmgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
                String deviceID = telmgr.getDeviceId();
                boolean isEmulator = "000000000000000".equalsIgnoreCase(deviceID);

                // get the bitmap
                if (isEmulator) {
                    ((myApp) getApplication()).setBitmapX(BitmapFactory.decodeFile(imageFileName));
                } else {
                    ((myApp) getApplication()).setBitmapX(BitmapFactory.decodeByteArray((byte[]) args[0], 0, ((byte[])args[0]).length));
                }

                ((myApp) getApplication()).setImageForDB(ImageTools.resizeBmp(((myApp) getApplication()).getBmp()));
                // convert the bitmap into a grayscale image and display it in the preview
                ((myApp) getApplication()).setImage(makeGrayScale());
                isSuccess = true;
            }
            catch (Exception connEx){
                errorMessageFromBkgndThread = getString(R.string.errcapture);
            }
            return isSuccess; 
        } 

        protected void onPostExecute(Boolean result) { 
            // Pass the result data back to the main activity 
            if (MyActivity.this.pd != null) { 
                MyActivity.this.pd.dismiss(); 
            } 
            if (result){
                ((ImageView) findViewById(R.id.apercu)).setImageBitmap(((myApp) getApplication()).getBmp());    
                ((myApp) getApplication()).setBitmapX(null);
            }
            else{
                // there was an error
                ErrAlert();
            }
        } 
    }     
};
private void ErrAlert(){
    // notify the user about the error
    AlertDialog.Builder dialog = new AlertDialog.Builder(this);
    ...
    dialog.create().show();
}

}

L'attività è terminato su un clic del pulsante, in questo modo:

Button use = (Button) findViewById(R.id.use);
use.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(MyActivity.this, NextActivity.class);
        intent.putExtra("dbID", "-1");
        intent.putExtra("category", category);
        ((myApp) getApplication()).setBitmapX(null);
        MyActivity.this.startActivity(intent);
        MyActivity.this.finish();
        }
    });

MemoryAnalyzer indicato la perdita di memoria a:

((myApp) getApplication ()) setBitmapX (BitmapFactory.decodeByteArray ((byte []) args [0], 0, ((byte []) args [0]) lunghezza).);.

Sono grato per ogni suggerimento, vi ringrazio in anticipo.

È stato utile?

Soluzione

è la vostra spazzatura filo raccolti dopo OnPostExecute si chiama o è ancora nella memoria?

Un Async compito non sarà annullata o distrutte al momento in cui l'attività è respinto. Se il filo è più o meno leggero e finiture dopo un piccolo tempo, basta tenerlo in funzione e aggiungere un MyActivity.this. isFinishing () clausola nel metodo OnPostExecute ().

Il tuo compito memorizza un riferimento implicito alle vostre MyActivity.this attività, perché si tratta di una classe privata all'interno l'attività. Ciò significa che il vostro attività non saranno spazzatura raccolti fino a quando le uscite di attività.

Altri suggerimenti

Si può cercare sotto frammento di codice

protected void onPostExecute(Boolean result) {
    if(YourActivity.this.isFinished()){
        //to smomething here
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top