为什么线程在我的示例中表现如此?

发布于 2024-12-16 17:55:46 字数 2906 浏览 1 评论 0原文

有人可以向我解释关于我最终几乎按其应有的方式工作的线程代码的两件事吗?我想每 x 秒在后台执行一项定期任务,并且能够随意停止和启动它。我根据我找到的示例进行了编码,但我不确定我是否以正确的方式进行了编码。出于调试目的,该任务使用自定义 showTime() 显示时间。

public class LoopExampleActivity extends Activity {

    TextView Napis, Napis2;
    Button button1,button_start,button_stop;
    Handler handler = new Handler();
    Boolean tread1_running = true;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Napis = (TextView) findViewById(R.id.textView1);
        Napis2 = (TextView) findViewById(R.id.textView2);
        button1 = (Button) findViewById(R.id.button1);
        button_stop = (Button) findViewById(R.id.button_stop);
        button_start = (Button) findViewById(R.id.button_start);


        button_stop.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick (View v) {
                tread1_running = false;
                                }
            });
        button_start.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick (View v) {
                tread1_running = true;


                                }
            });

        thread.start();


    }// endof  onCreate


    final Runnable r = new Runnable()
    {
        public void run() 
        {

            handler.postDelayed(this, 1000);
            showTime(Napis2);

        }
    };

    Thread thread = new Thread()
    {
        @Override
        public void run() {
            try {
                while(tread1_running) {
                    sleep(1000);
                    handler.post(r);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };

}

现在的问题是:
1)如果我用停止按钮停止我的线程会永远退出吗?

2)为什么我不能用start_button重新启动它?如果我在按钮中添加tread.start(),它会崩溃吗?

3)当我让线程运行并将条件放入处理程序时,我尝试了第二个版本。我可以让它工作的唯一方法是通过添加

if (thread1_running) {
                handler.postDelayed(this, 2000);
                showTime(Napis2);
            }

并更改线程启动中的条件来在

 while (true) 
but then I have an open thread that is running all the time and I start and stop it in a handler, and it posts more and more handlers.

处理程序中有条件地循环

所以,最后我想说的是:

final Runnable r = new Runnable()
{
    public void run() 
    {

        if (thread1_running) handler.postDelayed(this, 1000);
            showTime(Napis2);

    }
};

Thread thread = new Thread()
{
    @Override
    public void run() {
        try {
            while(true) {
                sleep(1000);
                if (thread1_running) handler.post(r);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};

正确的方法是启动和停止整个线程吗?或者说这是最好的方法?

Can someone explain to me 2 things about the thread code that I finally made almost working the way it should. I want to do a periodic task in the background every x seconds and be able to stop and start it at will. I coded that based on the examples I found, but I'm not sure if I made it in the right way. For the purpose of debugging, the task is displaying a time with custom showTime().

public class LoopExampleActivity extends Activity {

    TextView Napis, Napis2;
    Button button1,button_start,button_stop;
    Handler handler = new Handler();
    Boolean tread1_running = true;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Napis = (TextView) findViewById(R.id.textView1);
        Napis2 = (TextView) findViewById(R.id.textView2);
        button1 = (Button) findViewById(R.id.button1);
        button_stop = (Button) findViewById(R.id.button_stop);
        button_start = (Button) findViewById(R.id.button_start);


        button_stop.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick (View v) {
                tread1_running = false;
                                }
            });
        button_start.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick (View v) {
                tread1_running = true;


                                }
            });

        thread.start();


    }// endof  onCreate


    final Runnable r = new Runnable()
    {
        public void run() 
        {

            handler.postDelayed(this, 1000);
            showTime(Napis2);

        }
    };

    Thread thread = new Thread()
    {
        @Override
        public void run() {
            try {
                while(tread1_running) {
                    sleep(1000);
                    handler.post(r);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };

}

Now the questions are:
1)Will my thread quit forever if I stop it with the stop button?

2)Why can't I start it again with the start_button? If I add the tread.start() in a button, will it crash?

3) I tried a second version when I let the thread run and put a condition into the handler. The only way I can get it to work is to loop conditionaly in the handler by adding an

if (thread1_running) {
                handler.postDelayed(this, 2000);
                showTime(Napis2);
            }

And changing the condition in a thread start to

 while (true) 

but then I have an open thread that is running all the time and I start and stop it in a handler, and it posts more and more handlers.

So, finally I get to the point it looks like that:

final Runnable r = new Runnable()
{
    public void run() 
    {

        if (thread1_running) handler.postDelayed(this, 1000);
            showTime(Napis2);

    }
};

Thread thread = new Thread()
{
    @Override
    public void run() {
        try {
            while(true) {
                sleep(1000);
                if (thread1_running) handler.post(r);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};

Is the proper way to do that is to start and stop a whole thread? Or that is the best way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

就此别过 2024-12-23 17:55:46

在我看来,实现类似目标的最佳方法是 postDelayed(Runnable, long)

你可以做这样的事情。类定义:

private Handler mMessageHandler = new Handler();

private Runnable mUpdaterRunnable = new Runnable() {
        public void run() {
            doStuff();
            showTime(Napis2);
            mMessageHandler.postDelayed(mUpdaterRunnable, 1000);
        }
};

并像这样控制真正的运行/停止:

启动:

mMessageHandler.postDelayed(mUpdaterRunnable, 1000);

停止:

mMessageHandler.removeCallbacks(mUpdaterRunnable);

在我看来,这要简单得多。

The best way to achieve something like that would be, in my humble opinion, to postDelayed(Runnable, long).

You could do something like this. Class definition:

private Handler mMessageHandler = new Handler();

private Runnable mUpdaterRunnable = new Runnable() {
        public void run() {
            doStuff();
            showTime(Napis2);
            mMessageHandler.postDelayed(mUpdaterRunnable, 1000);
        }
};

And control true run/stop like this:

To start:

mMessageHandler.postDelayed(mUpdaterRunnable, 1000);

And to stop:

mMessageHandler.removeCallbacks(mUpdaterRunnable);

It's much much simpler, in my humble opinion.

遥远的她 2024-12-23 17:55:46

状态机描述的线程在Java中。

当线程退出其 run 方法时,它会进入停止状态并且无法重新启动。

您应该始终通过将线程从 run 方法中取出来停止线程,这是正确的方法。

如果您想“重新启动线程”,请启动线程类的新实例。

你应该更好地封装你的线程及其运行字段。它应该位于您的线程类中,并且该类应该提供一个公共方法来切换布尔值。没有人关心你的数据结构,隐藏它们。 :)

您应该考虑对您的可运行对象使用 runOnUIThread,它比处理程序更容易使用。

Threads a described by a state machine in java.

When a thread get outs of its run method, it enters in the stopped state and can't be restarted.

You should always stop a thread by getting it out of its run method as you do, it s the proper way to do it.

If you want to "restart the thread", start a new instance of your thread class.

You should better encapsulate your thread and its running field. It should be inside your thread class and the class should offer a public method to swich the boolean. No one cares about your datastructure, hide them. :)

You should consider using runOnUIThread for your runnable, its much easier to use than handlers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文