【问题标题】:Android Memoryleak in code代码中的 Android 内存泄漏
【发布时间】:2012-05-17 06:34:17
【问题描述】:

我试图理解内存泄漏的概念。我尝试了这段代码并尝试了从相关帖子中找到的几种方法,但我无法解决问题。需要帮助了解此代码中发生内存泄漏的位置。我的应用程序只有 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.<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)

【问题讨论】:

  • 在这段代码中看起来没有任何类型的内存泄漏,也许代码的其他部分有内存泄漏。你也不需要在onStop()onPause() 中的对象上调用 null。这将导致应用程序恢复的延迟。
  • 谢谢。是的,我最初只在 ondestroy 方法中尝试过,但即使在那之后我也遇到了内存泄漏。所以也添加到其他方法中。我现在将发布完整的代码。
  • 示例:'RedImage = (ImageView) findViewById(R.id.Red);` 我看到您在两个活动中创建相同的图像对象。

标签: java android memory memory-leaks


【解决方案1】:

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

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

希望它会有所帮助。

编辑:根据您更新的问题

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

【讨论】:

  • 请参阅我看到内存泄漏的日志数据。另外,我的类文件中没有任何静态引用,它可能包含永久引用
  • 不是内存泄漏而是窗口泄漏异常。在您完成活动之前关闭或关闭您的对话框。这将解决您的问题。
  • 嘿,谢谢。一旦我关闭了对话框,我就没有在 log cat 中得到异常。
【解决方案2】:

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

MATDemoActivity 来电

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

然后你从SecondActivity打来电话

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

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

尝试解决这些问题,看看是否可行。

【讨论】:

  • “你正在重新创建每个活动中的所有对象” - 你怎么说?您能否提供更多见解?
【解决方案3】:

从日志中,我认为问题的原因是您显示了一个对话框但没有关闭它,然后您将对话框分配为 null 并开始另一个活动。

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

因此活动将泄漏对话框(对话框是窗口)。无论如何,如果您不需要显示对话框,则应将其关闭。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    • 2023-04-01
    相关资源
    最近更新 更多