代码中的Android Memoryleak

我试图理解内存泄漏的概念。 我尝试了这个代码并尝试了一些我从相关post中找到的方法,但我无法解决问题。 需要帮助来了解此代码中发生内存泄漏的位置。 我的申请只有2项活动

//第一活动

package com.pace.mat; import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.Window; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class MATDemoActivity extends Activity implements OnClickListener { private Dialog dialog1; private Button btnSubmit; private Context myClassContext; private ImageView RedImage,BlueImage,Yellow,Orange,Green; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); myClassContext = this; RedImage = (ImageView) findViewById(R.id.Red); BlueImage = (ImageView) findViewById(R.id.Blue); Yellow = (ImageView) findViewById(R.id.Yellow); Orange = (ImageView) findViewById(R.id.Orange); Green = (ImageView) findViewById(R.id.Green); RedImage.setImageResource(R.drawable.red); BlueImage.setImageResource(R.drawable.blue); Yellow.setImageResource(R.drawable.yellow); Orange.setImageResource(R.drawable.orange); Green.setImageResource(R.drawable.green); btnSubmit = (Button)findViewById(R.id.btnSubmitAtFirst); btnSubmit.setOnClickListener(this); } public void onClick(View arg0) { // TODO Auto-generated method stub if(arg0 == (View)btnSubmit) { dialog1=new Dialog(myClassContext); Window window = dialog1.getWindow(); window.setBackgroundDrawableResource(android.R.color.transparent); window.requestFeature(window.FEATURE_NO_TITLE); dialog1.setContentView(R.layout.progress_indicator); dialog1.show(); // Doing a network intensive task if(dialog1 !=null) { dialog1 = null; myClassContext = null; window = null; } Intent i = new Intent(MATDemoActivity.this,SecondActivity.class); startActivity(i); } } @Override public void onStop() { super.onStop(); myClassContext = null; dialog1 = null; RedImage = null; BlueImage = null; Yellow = null; Orange = null; Green=null; this.finish(); } @Override public void onPause() { super.onPause(); myClassContext = null; dialog1 = null; RedImage = null; BlueImage = null; Yellow = null; Orange = null; Green=null; this.finish(); } @Override public void onDestroy() { super.onDestroy(); myClassContext = null; dialog1 = null; RedImage = null; BlueImage = null; Yellow = null; Orange = null; Green=null; this.finish(); } } 

//第二个活动

 package com.pace.mat; import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.Window; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class SecondActivity extends Activity implements OnClickListener { private Dialog dialog1; private Button btnSubmit; private Context myClassContext1; private ImageView RedImage,BlueImage,Yellow,Orange,Green; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.secondactivity); myClassContext1 = this; RedImage = (ImageView) findViewById(R.id.Red); BlueImage = (ImageView) findViewById(R.id.Blue); Yellow = (ImageView) findViewById(R.id.Yellow); Orange = (ImageView) findViewById(R.id.Orange); Green = (ImageView) findViewById(R.id.Green); RedImage.setImageResource(R.drawable.red); BlueImage.setImageResource(R.drawable.blue); Yellow.setImageResource(R.drawable.yellow); Orange.setImageResource(R.drawable.orange); Green.setImageResource(R.drawable.green); btnSubmit = (Button)findViewById(R.id.btnSubmitAtFirst); btnSubmit.setOnClickListener(this); } public void onClick(View v) { // TODO Auto-generated method stub if(v == (View)btnSubmit) { dialog1=new Dialog(myClassContext1); Window window = dialog1.getWindow(); window.setBackgroundDrawableResource(android.R.color.transparent); window.requestFeature(window.FEATURE_NO_TITLE); dialog1.setContentView(R.layout.progress_indicator); dialog1.show(); // Uploading an Image to network if(dialog1 !=null) { dialog1 = null; myClassContext1 = null; window = null; } Intent i = new Intent(this,MATDemoActivity.class); startActivity(i); } } @Override public void onStop() { super.onStop(); this.finish(); } @Override public void onPause() { super.onPause(); this.finish(); } @Override public void onDestroy() { super.onDestroy(); myClassContext1 = null; dialog1 = null; RedImage = null; BlueImage = null; Yellow = null; Orange = null; Green=null; this.finish(); } } 

//当我从第一次到第二次活动时,记录CAT数据

 05-17 12:12:43.323: E/WindowManager(2264): Activity com.pace.mat.SecondActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44f63b88 that was originally added here 05-17 12:12:43.323: E/WindowManager(2264): android.view.WindowLeaked: Activity com.pace.mat.SecondActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44f63b88 that was originally added here 05-17 12:12:43.323: E/WindowManager(2264): at android.view.ViewRoot.(ViewRoot.java:247) 05-17 12:12:43.323: E/WindowManager(2264): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148) 05-17 12:12:43.323: E/WindowManager(2264): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) 05-17 12:12:43.323: E/WindowManager(2264): at android.view.Window$LocalWindowManager.addView(Window.java:424) 05-17 12:12:43.323: E/WindowManager(2264): at android.app.Dialog.show(Dialog.java:241) 05-17 12:12:43.323: E/WindowManager(2264): at com.pace.mat.SecondActivity.onClick(SecondActivity.java:54) 05-17 12:12:43.323: E/WindowManager(2264): at android.view.View.performClick(View.java:2408) 05-17 12:12:43.323: E/WindowManager(2264): at android.view.View$PerformClick.run(View.java:8816) 05-17 12:12:43.323: E/WindowManager(2264): at android.os.Handler.handleCallback(Handler.java:587) 05-17 12:12:43.323: E/WindowManager(2264): at android.os.Handler.dispatchMessage(Handler.java:92) 05-17 12:12:43.323: E/WindowManager(2264): at android.os.Looper.loop(Looper.java:123) 05-17 12:12:43.323: E/WindowManager(2264): at android.app.ActivityThread.main(ActivityThread.java:4627) 05-17 12:12:43.323: E/WindowManager(2264): at java.lang.reflect.Method.invokeNative(Native Method) 05-17 12:12:43.323: E/WindowManager(2264): at java.lang.reflect.Method.invoke(Method.java:521) 05-17 12:12:43.323: E/WindowManager(2264): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 05-17 12:12:43.323: E/WindowManager(2264): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 05-17 12:12:43.323: E/WindowManager(2264): at dalvik.system.NativeStart.main(Native Method) 

你的代码似乎没有任何内存泄漏。 并且大多数时候内存泄漏是由于保持对Context的长期引用。

这是Romain Guy的一篇好文章,它将帮助您详细了解内存泄漏。 看看吧 。

希望它会有所帮助。

编辑:根据你更新你的问题

看着你的日志后,似乎没有内存泄漏,它的窗口泄露exception。 在完成活动之前关闭或关闭对话框。 这将解决您的问题。

看起来你正在重复地从另一个活动中调用一个活动,就像你循环进入活动并切换它们一样。

MATDemoActivity调用

 Intent i = new Intent(MATDemoActivity.this,SecondActivity.class); startActivity(i); 

然后从你正在调用的SecondActivity

 Intent i = new Intent(this,MATDemoActivity.class); startActivity(i); 

您也在重新创建每个活动中的所有对象,而不是在两个活动之间共享它们。

尝试修复这些问题,看看是否有效。

从日志中,我认为问题的原因是您显示了一个对话框但没有解除它,然后您将对话框指定为null并启动另一个活动。

 if(dialog1 !=null) { dialog1 = null; myClassContext1 = null; window = null; } 

因此活动将泄漏对话框(对话框是窗口)。 无论如何,如果你不需要显示对话框,你应该忽略它。