从内存泄漏这个Runnable的安全吗? [英] Is this Runnable safe from memory leak?

查看:947
本文介绍了从内存泄漏这个Runnable的安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Java中的总初学者,已经创建了一个简单的Java的Andr​​oid片段,其中在1.5秒的Runnable后,我改变的TextView 的Hello World 霍拉世界报。它完美的作品,基本上是一个的WeakReference 应该prevent从右侧发生此内存泄漏?我有一个疑问,如果有绝对每当设备的方向不会发生内存泄漏。我很愿意来检查这一点,但不能设法改变方向在我的Andr​​oid效仿。

I am a total beginner in Java and have created a simple Java Android snippet where in a Runnable after 1,5 seconds I change the TextView from Hello World to Hola Mundo. It works flawlessly, basically a WeakReference should prevent this memory leak from happening right? I have a doubt if there's absolutely no memory leak whenever device orientation occurs. I would love to check this but can't manage to change orientation in my emulated Android.

这是code:

package com.example.helloworld;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
import android.util.Log;
import java.lang.ref.WeakReference;

public class HelloWorldActivity extends Activity
{
    private Handler h = new Handler();
    private static TextView txtview;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        txtview = (TextView) findViewById(R.id.mainview);

        h.postDelayed(new WeakRunnable(txtview),1500);
    }

    private static final class WeakRunnable implements Runnable {
        private final WeakReference<TextView> mtextview;

        protected WeakRunnable(TextView textview){
            mtextview = new WeakReference<TextView>(textview);
        }

            @Override
            public void run() {
                TextView textview = mtextview.get();
                if (textview != null) {
                    txtview.setText("Hola Mundo");
                    textview = null; // No idea if setting to null afterwards is a good idea
                }
                Log.d("com.example.helloworld", "" + textview);
            }
    }           

}

修改

这是一个从内存泄漏安全的,但几个答案也涉及UI线程阻塞。事实上,这code运行在主(UI)线程处理程序。要手动生成一个新的线程,我产生线程如下:

It's safe from memory leaks but a few answers were also concerned with UI thread blocking. In fact this code runs the Handler in the main (UI) thread. To spawn a new thread I'm spawning a thread manually as follows:

package com.example.helloworld;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;
import android.util.Log;
import java.lang.ref.WeakReference;

public class HelloWorldActivity extends Activity
{

    private static TextView txtview;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        txtview = (TextView) findViewById(R.id.mainview);

        Thread t = new Thread(new WeakRunnable(txtview));
        t.start();
    }

    private static final class WeakRunnable implements Runnable {
        private final WeakReference<TextView> mtextview;

        protected WeakRunnable(TextView textview){
            mtextview = new WeakReference<TextView>(textview);
        }

            @Override
            public void run() {
                TextView textview = mtextview.get();
                if (textview != null) {
                    /*
                    try {
                        Thread.sleep(1500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    */
                    txtview.setText("Hola Mundo");
                    textview = null;
                }
                Log.d("com.example.helloworld", "" + Thread.currentThread().getName()); // Outputs "Thread-<num>" if not running on UI thread
            }
    }           

}

现在的问题是,我似乎不能耽误以任何方式衍生线程,否则它的工作原理。

The issue now is that I can't seem to delay the spawned thread in any way, otherwise it works.

try {
    Thread.sleep(1500);
} catch (InterruptedException e) {
    e.printStackTrace();
}

使应用程序退出本身,我不知道为什么。有个声音告诉我,我推迟了错误的方式。

makes the app quit itself and I don't get why. Something tells me I'm delaying it the wrong way.

EDIT2

由于链接@EugenMatynov给我:更新UI从另一个线程Android的我明白了为什么应用程序辞去。这一切都归结到原因的您不能从非主线程其他线程调用用户界面的方法。的,这是不好的做法来更新从另一个线程的用户界面。

Thanks to the link @EugenMatynov give me: update ui from another thread in android I understood why the app quitted. It all comes down to the reason You can't call UI methods from threads other than the main thread. and it's bad practice to update the UI from another thread.

推荐答案

我觉得你的code是如果你使用无泄漏:

I think your code is leak free if you use :

private static Handler h = new Handler(); 

txtview.postDelayed(new WeakRunnable(txtview),1500);

因为你的存储视图作为WeakReference的。方法:

because you have stored the view as a WeakReference. the method:

txtview.postDelayed(new WeakRunnable(txtview),1500);

简单地调用UI线程的主处理,所以如果活动被销毁的观点为null,并且可运行的剂量无关。

simply call main handler of the UI thread so if the activity is destroyed the view is null and the runnable dose nothing.

也因为了WeakReference的活性可以被垃圾收集,因为没有强有力的参考吧。

also because of the weakreference the activity can be garbage collected because there is no strong reference to it.

这篇关于从内存泄漏这个Runnable的安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆