有人可以向我解释有关线程代码的两件事,我最终几乎按照应该的方式工作。我想每隔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)当我让线程运行并将一个条件放入处理程序时,我尝试了第二个版本。我能让它工作的唯一方法是通过添加
来在处理程序中循环conditionalyif (thread1_running) {
handler.postDelayed(this, 2000);
showTime(Napis2);
}
将线程中的条件更改为
while (true)但是我有一个一直运行的开放线程,我在处理程序中启动并停止它,并且它发布的内容越来越多处理程序。
所以,最后我看到它的样子:
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();
}
}
};
这样做的正确方法是启动和停止整个线程吗?或者那是最好的方式?
答案 0 :(得分:0)
在java中用state machine描述的线程。
当线程离开其run方法时,它进入停止状态并且无法重新启动。
你应该像通常那样通过运行方法来停止一个线程,这是正确的方法。
如果要“重新启动线程”,请启动线程类的新实例。
您应该更好地封装您的线程及其运行字段。它应该在你的线程类中,类应该提供一个公共方法来切换布尔值。没有人关心你的数据结构,隐藏它们。 :)
您应该考虑将runOnUIThread用于runnable,它比处理程序更容易使用。
答案 1 :(得分:0)
以我的拙见,实现这类目标的最佳方法是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);
在我的拙见中,这简单得多了。