如果通过runOnUiThread从AsyncTask启动,则线程仍处于NEW状态

时间:2011-06-08 14:31:52

标签: java android android-asynctask

这是我编写的一个示例应用程序,用于重现我遇到的与内存泄漏相关的问题:

 package a.b.mapleak;
 import android.app.Activity;
 import android.content.Context;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
 import android.widget.TextView;

public class MapLeak extends Activity
{
TextView callVoidText, getNewDataText, getDataStringText;
Button callVoidButton, getNewDataButton, getDataStringButton;
Handler callbackHandler;
MemoryLeak memleak;
private LoadAccountsTask mLoadAccountsTask = null;
private class LoadAccountsTask extends AsyncTask<Void, Void, Object[]> {

    private int mCursor1;
    private int mCursor2;
    private Context context;
    private UITask t = new UITask();


    @Override
    protected Object[] doInBackground(Void... params) {

        runOnUiThread(t);

        // Create the summaries cursor
        mCursor1 = 1;
        mCursor2 = 2;
        return new Object[] { mCursor1, mCursor2};
    };
  private class UITask extends Thread {
        @Override
        public void run() {
            int i = 2;
            while (i>0) {
                i--;
            }
            Thread.State state=t.getState();
            Log.e(ALARM_SERVICE, "Thread state in run is " + state.toString());

        }
    }

}


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    getDataStringText = (TextView) findViewById(R.id.getDataString_text);
    getDataStringButton = (Button) findViewById(R.id.getDataString_button);
    getDataStringButton.setOnClickListener(new Button.OnClickListener() {
        long i = 0;
        public void onClick(View v) {
           if (mLoadAccountsTask != null) mLoadAccountsTask.cancel(true);
           mLoadAccountsTask = (LoadAccountsTask) new LoadAccountsTask(this).execute();
        }
    });

}

}

我发现从runOnUiThread开始的线程从未退出。对于一些我不知道任务正在运行的原因,但是来自

的输出
Log.e(ALARM_SERVICE, "Thread state in run is " + state.toString());

每次都是“运行中的线程状态是新的”,例如''线程已经创建,但从未启动过。''。因此,线程一直在运行,阻止“LoadAccountsTask”类被垃圾回收。因此,在这个例子中,每次按下按钮 - 新的“LoadAccountsTask”出现在内存中。

但是,如果要替换

private class UITask extends Thread 

private class UITask implements Run

没有内存泄漏,线程成功退出。当然state = t.getState();在这种情况下不起作用,应予以评论。

有人解释为什么会这样吗?

1 个答案:

答案 0 :(得分:0)

关注您的直接关注,runOnUiThread()需要Runnable。虽然Thread确实实施了Runnable,但runOnUiThread()不会将其视为Thread。请将Runnable传递给runOnUiThread()

其次,永远不要从runOnUiThread()致电doInBackground()。只需执行RunnableonPreExecute()onPostExecute()的工作,这些工作在主应用程序主题上执行。

第三,如果您曾写过真正的Thread,请不要在其中忙碌。