수정할 수없는 메모리 누수가 발생합니다. 나는 MemoryAnalizer를 사용하여 그것이 어디에서 발생했는지 발견했지만, 나는 그것을 제거하기 위해 헛되게 노력했다.Android : AsyncTask로 인한 메모리 누수가 발생했습니다.
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();
}
}
활성은 다음과 같이, 버튼 클릭에 종료된다 :
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은 메모리 누수를 나타내는 :
((여기서 코드는 getApplication()) setBitmapX (BitmapFactory.decodeByteArray ((byte []) args [0], 0, ((byte []) args [0]).
어떤 제안이 있어도 감사드립니다. 미리 감사드립니다.
세미 추측을 시도 할 수 있습니다 : 당신이'를 호출해야한다 귀하의'Bitmap' 객체에 재활용을()'당신이 그들과 함께 완료 후? 또한 'PickerActivity.this'에 대한 호출은 사용자가 지정한 컨텍스트에서 의미가없는 것처럼 보입니다. 그리고 자주 사용되는'(myApp) getApplication()'호출을 캐시해야합니다. –
Christopher, 답장을 보내 주셔서 감사합니다. 실제로 PickerActivity는 MyActivity입니다 (게시물을 편집했습니다). 비트 맵은 응용 프로그램 수준에서 정의됩니다. 그 이유는 내가 후속 작업에서 필요하기 때문에 그들을 재활용하지 않기 때문입니다. 응용 프로그램과 MemoryAnalyzer를 디버깅하면 MyActivity가 종료 된 경우에도 ManageCaptureTask가 지속된다는 것을 알 수 있습니다.이 작업은 수행 방법을 모르는 것입니다. 즉, 비동기 작업을 종료하십시오. 나는 게시물을 편집하고 MyActivity가 종료되고 다음 활동이 시작되는 onClick 이벤트를 추가했습니다. – Manu
나는'Application'에서'Bitmap'을 사용하고있는 것을 보았습니다 만, 어떤 시점에서 이것을'null'로 설정하는 것을 보았습니다. 그래서 그 부분에서 재활용되어야하는지 의아해했습니다. –