我正在尝试制作一个简单的小程序,它将每秒增加一个数字。在这种情况下,我正在实现一个线程,该线程应该每秒循环一次,并在每次循环时向"potato"添加 1。这工作正常,直到它回到显示方法 potatoDisp()。由于某种原因,这会导致我的应用程序崩溃。从 run() 中删除 potatoDisp() 可以解决此问题,但显示不会随着"potato"的增加而更新。
public int potato = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
potatoDisp();
start();
}
public void potatoDisp() {
TextView text = (TextView) findViewById(R.id.textView1);
text.setText("You currently have " + potato + " potatoes");
}
public void start() {
Thread thread = new Thread(this);
thread.start();
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
potato++;
potatoDisp();
}
}
我正在为Android应用程序执行此操作,如果有帮助的话。我尝试过寻找答案,但是当涉及到处理线程的正确方法时,我感到非常迷茫。
你需要一个像这样的可运行/处理程序:
private Runnable potatoRun = new Runnable() {
@Override
public void run () {
potatoDisp();
}
};
然后更改
potatoDisp();
自:
runOnUiThread(potatoRun);
不在 UI 线程上时,无法更新视图。
在后台更新UI
时遇到异常。因为,potatoDisp();
是从后台调用的Thread
但该函数更新了UI
它会给您带来问题。您需要用runOnUiThread()
来调用它。
@Override
public void run() {
while (true) {
try
{
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
potato++;
runOnUiThread(new Runnable()
{
@Override
public void run()
{
potatoDisp();
}
});
}
}
这样的事情应该有效。
问题是您正在尝试在主 UI 线程以外的线程上更新 UI(调用 text.setText(...)
)。
虽然我建议使用 TimerTask
而不是调用 Thread.sleep(...)
,但有两种主要方法可以编辑当前代码以按预期工作。
-- 使用Handler
定义一个 Handler
类,该类将接受消息并根据需要更新 UI。例如:
private final String POTATO_COUNT = "num_potatoes";
Handler handler = new Handler() {
public void handleMessage(Message msg) {
int numPotatoes = msg.getData.getInt(POTATO_COUNT);
mText.setText("You currently have " + numPotatoes + " potatoes");
}
}
然后,在要调用处理程序以更新文本视图的代码中,无论您是否在主 UI 线程上,请执行以下操作:
Bundle bundle = new Bundle();
bundle.putInt(POTATO_COUNT, potato);
Message msg = new Message();
msg.setData(bundle);
handler.sendMessage(msg);
-- 呼叫runOnUiThread(...)
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return;
}
potato++;
runOnUiThread(new Runnable()
{
public void run()
{
potatoDisp();
}
}
}
}
我认为您应该使用异步任务从线程更新 UI:http://developer.android.com/reference/android/os/AsyncTask.html