繁体   English   中英

使用 android 处理程序时,如何解决有关 memory 泄漏的警告?

How can I resolve warnings about memory leaks when using android Handler?

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我是学习android的初学者。 我在学习 Thread 时使用了 Handler。 顺便说一句,我在 android studio 中使用 Handler 警告 memory 泄漏。 我搜索了很多不同的问题,但没有与我的案例相对应的部分。 使用处理程序时,如何解决有关 memory 泄漏的警告?

public class HandlerActivity extends AppCompatActivity implements Runnable {

    ProgressBar pb;
    TextView txtRate;
    Button btnStart;
    static int value;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.progress);

        pb = findViewById(R.id.pb);
        txtRate = findViewById(R.id.txtRate);
        btnStart = findViewById(R.id.btnStart);

        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Thread th = new Thread(HandlerActivity.this);
                th.start();
            }
        });
    }

        Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            pb.setProgress(value);
            txtRate.setText("Process : " + value + "%");
        }
    };

    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            value = i;

            handler.sendEmptyMessage(0);

            try {
                Thread.sleep(100);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(HandlerActivity.this, "Progress Done !", Toast.LENGTH_SHORT).show();
            }
        });
    }
}
2 个回复

基本上TextView或任何其他View持有代表相应ActivityContext object 的引用。 当您在Thread中保留对任何View的强引用时,您不仅存储了View object,而且还存储了一个Context object 代表创建它的Activity 现在由于Thread不与 Activity 生命周期绑定,即使在Activity被销毁后它们也会继续运行。 如果是这种情况, Thread将通过该View object 保存已破坏的Activity引用,从而创建 memory 泄漏。

上述问题可以通过存储View object 的弱引用来解决,以便 GC 可以在必要时对其进行垃圾回收。 通过以下方式,您可以摆脱 memory 泄漏:

public class HandlerActivity extends AppCompatActivity implements Runnable {
    WeakReference<ProgressBar> pb;
    WeakReference<TextView> txtRate;
    Button btnStart;
    static int value;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        pb = new WeakReference<>(findViewById(R.id.pb)); // you may require to cast findViewById() to ProgressBar
        txtRate = new WeakReference<>(findViewById(R.id.txtRate));  // you may require to cast findViewById() to TextView
        ...
    }

    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if(pb.get()!=null) pb.get().setProgress(value);
            if(txtRate.get()!=null) txtRate.get().setText("Process : " + value + "%");
        }
    };

    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            // Its always recommended to check if activity is running and stop the thread if not running
            if(isFinishing() || isDestroyed()) {
                return;
            }
        }
    }
}

Roaim, Mark Keen 在他们的帮助下,我解决了这个问题并自己给出了完整的答案。 感谢 Roaim,Mark Keen。

public class HandlerActivity extends AppCompatActivity implements Runnable {

ProgressBar pb;
TextView txtRate;
Button btnStart;
int value;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.progress);

    pb = findViewById(R.id.pb);
    txtRate = findViewById(R.id.txtRate);
    btnStart = findViewById(R.id.btnStart);

    btnStart.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Thread th = new Thread(HandlerActivity.this);
            th.start();
        }
    });
}

private static class WeakHandler extends Handler {
    private final WeakReference<HandlerActivity> mWeakActivity;

    private WeakHandler(HandlerActivity AppCompatActivity) {
        mWeakActivity = new WeakReference<>(AppCompatActivity);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        HandlerActivity _activity = mWeakActivity.get();

        if (_activity != null) {

            switch (msg.what) {
                case 0:
                    _activity.pb.setProgress(_activity.value);
                    _activity.txtRate.setText("Process : " + _activity.value + "%");
                    break;
            }
        }
    }
}

private final WeakHandler mHandler = new WeakHandler(this);

@Override
public void run() {
    for (int i = 1; i <= 100; i++) {
        value = i;

        mHandler.sendEmptyMessage(0);

        try {
            Thread.sleep(100);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(HandlerActivity.this, "Progress Done !.", Toast.LENGTH_SHORT).show();
        }
    });
}

}

1 ios:如何解决此 memory 泄漏警告

我得到以下代码行: 当我在 xcode 中运行 Product-&gt;Analyse 时,它给了我警告: 所以这意味着我不会释放我的 CGColor。 因此,我认为一个好的解决方案如下: 但我仍然收到相同的泄漏警告。 如何修复问题? ...

2 我如何解决由ContextMenuStrips不处理引起的内存泄漏

我在这里问了这个问题(我该如何解决由ContextMenuStrip引用的对象引起的内存泄漏 ),并认为已经解决了该问题,但是明显的修复方法无效。 我已经搜索了该问题,并发现了许多有关由于ContextMenuStrips而导致的内存泄漏的问题和博客,但没有找到具体的答案。 我创建了一个小的 ...

4 内存泄漏。 我该如何解决它们

我遇到了几次内存泄漏。 所有代码均位于代码的最后位置-[ASIHTTPRequest somemethod]。 早些时候,我以为是ASIhtt库正在泄漏​​内存。 但是,看起来它可能只是指向创建对象的位置,并且泄漏的原因实际上与代码中的原因相同。 下面是堆栈内存泄漏之一的示例。 我需要 ...

5 如何解决内存泄漏?

我制作了这个小脚本来ping google.pt,并对ping结果执行一些操作。 问题是,如果让脚本运行一段时间,它将使用越来越多的RAM。 我似乎找不到错误,您能帮我吗? 编辑:getPingValue方法: 而take actionFromPingValueMetho ...

7 如何解决内存泄漏?

经过长时间的配置文件测试后,我发现在viewdidload部分中发生了我的一个“ .m”文件内存泄漏。 我检查了一下,xcode突出显示了我已使用值初始化选取器数组的部分。 我的程序使用选择器进行用户输入。 我的程序中有3 5种不同的视图。 第一个是免责声明,第二个是菜单,用户可以在其中 ...

8 我如何解决这个内存泄漏

我正在尝试重新创建向量类,我相信我的代码中存在内存泄漏,但我不知道如何解决。 在我的 Visual Studio 中使用 CRT 库,它告诉我有一个假设的内存泄漏,每次调用该保留时都会增加一倍。 我不太确定为什么会这样,或者是否有内存泄漏。 内存泄漏检测说它是保留函数中的这一行int* temp ...

9 如何解决这个内存泄漏?

我从servin.com网站上获得了以下代码。 尽管代码有效,但仪器报告内存泄漏。 我没有在代码中看到任何alloc,retain,copy,所以我无法弄清楚如何解决这个内存泄漏问题。 仪器的代码和结果如下。 任何帮助,将不胜感激。 仪器的结果...... 泄露的对象 - ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM