我卡住了內存泄漏,我無法修復。我使用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指示的存儲器泄漏於:
(( setApplication())。setBitmapX(BitmapFactory.decodeByteArray((byte [])args [0],0,((byte [])args [0])。
我很感激任何建議,謝謝您提前。
半猜測:你應該可以調用'再循環()'您'Bitmap'對象你與他們完成之後? 此外,對'PickerActivity.this'的調用在您給出的上下文中似乎沒有意義。而且你應該緩存經常使用的'(myApp)getApplication()'調用。 – 2010-06-13 22:55:32
克里斯托弗, 謝謝你的回覆,事實上PickerActivity是MyActivity(我編輯了這篇文章);位圖在應用程序級別定義,這就是爲什麼我不回收它們,因爲我在隨後的活動中需要它們。 調試應用程序和MemoryAnalyzer告訴我,即使MyActivity終止,ManageCaptureTask仍然存在,這是我不知道該怎麼做的:終止該異步任務。 我編輯帖子,添加onClick事件,其中MyActivity終止並啓動下一個活動。 – Manu 2010-06-14 09:06:05
我看到你在'Application'中使用'Bitmap',但是在某個時候看到你把它設置爲'null',所以想知道它是否應該在那個時候回收。 – 2010-06-14 09:24:27