以下代码是我目前正在使用的,但是有一个问题是Toast正在显示,所以它可能是在UI线程中不是吗?我不希望run()函数在UI线程上运行,因为我可能会在那里添加一些繁重的下载。但是,我想重复执行这段代码(每9000ms之后)所以我必须做什么,要么让这个运行脱离UI线程,要么解决我的问题。谢谢。
final Handler handler = new Handler();
Thread feedthread = new Thread()
{
@Override
public void run() {
super.run();
Toast.makeText(context, "UI", Toast.LENGTH_SHORT).show();
handler.postDelayed(this, 9000);
}
};
handler.postDelayed(feedthread, 9000);
请不要向我推荐AsyncTask,除非有办法重复代码而不使用while循环浪费资源或设置线程进入休眠状态。我想回答我的问题,而且不想要在UI线程上运行代码。
答案 0 :(得分:0)
您需要调用 runOnUiThread 方法来显示Toast
final Handler handler = new Handler();
Thread feedthread = new Thread()
{
@Override
public void run() {
super.run();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, "UI", Toast.LENGTH_SHORT).show();
}
});
handler.postDelayed(this, 9000);
}
};
handler.postDelayed(feedthread, 9000);
答案 1 :(得分:0)
您想使用AsyncTask课程。这是一个展示其工作原理的示例:
// Async Task Class
private class MyTask extends AsyncTask<String, String, String> {
// (Optional) Runs on the UI thread before the background task starts
@Override
protected void onPreExecute() {
super.onPreExecute();
// Do some UI stuff if needed
}
// Runs on a background thread
@Override
protected String doInBackground(String... param) {
String url = param[0];
// Do something with the param, like kick off a download
// You can also use publishProgress() here if desired at regular intervals
/*while (isDownloading) {
publishProgress("" + progress);
}*/
return null;
}
// (Optional) Runs on the UI thread periodically during the background task via publishProgress()
protected void onProgressUpdate(String... progress) {
// Update UI to show progress
/* prgDialog.setProgress(Integer.parseInt(progress[0])); */
}
// (Optional) Runs on the UI thread after the background task completes
@Override
protected void onPostExecute(String file_url) {
// Do some UI stuff to show completion of the task (if needed)
}
}
您可以像这样运行任务:
String url = getInternetUrl();
new MyTask().execute(url);
答案 2 :(得分:0)
new Thread(new Runnable(){
private boolean stopped = false;
@Override
public void run(){
while(!stopped) {
// Do, do, do...
try {
Thread.Sleep(9000);
} catch(Exception e){}
}
}
}).start();
此外,您可以使用Android处理程序类定期运行代码。这要求您有一个looper准备的线程来附加处理程序。基本上,一个循环准备好的线程会分配一个队列,发布到该线程的每条消息都将按队列方式排队并逐个处理。
这种方法与前一种方法有所不同,如果你在后台线程中做了很多工作以便花费一些时间,那么后续排队的消息将比间隔更快地处理(在这种情况下,9秒) )。因为启用了循环器的线程会立即处理下一个排队的消息,一旦它们完成了前一个消息。
注意:您不应该[并且不能]使用此方法作为服务的替代方案。这个新创建的线程确实需要一个底层组件(Activity或Service)来保持它活着。