I am trying to understand the concept of memory leaks. I tried this code and tried few ways i found from related posts but i could not solve the issue. Need help on understanding where memory leak happens in this code. My application has only 2 activities
//First Activity
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();
}
}
// Second Activity
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();
}
}
// LOG CAT DATA WHEN I MOVE FROM FIRST TO SECOND ACTIVITY
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.<init>(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)
Look like you are calling One activity from another repetitively, it's like you are looping into activities and switching them.
MATDemoActivity
callsand then from
SecondActivity
you are callingalso you are recreating all the objects in each activity instead of sharing them between two activities.
try fixing these problems and see if that works.
your code does not seem to have any memory leak. and most of the times memory leaks are due to keeping a long-lived reference to a Context.
Here is a good article by Romain Guy which will help you to understand Memory leaks in detail. check it out.
Hope it will help.
EDIT: as per you updated your question
After looking at your log its seems that there is no memory leak its window leaked exception. close or dismiss your dialog before you finish your activity. this will resolve your problem.
From the log, I think the cause of the problem is that you show a dialog but didn't dismiss it, then you assign the dialog to null and start another activity.
So the activity will leak the dialog(dialog is the window). Anyway if you don't need a dialog showing, you should dismiss it.