[英]Does TimerTask executing in new thread
我可以认为run
中的代码将在新线程中执行或者我必须使用AsyncTask
吗?
Timer myTimer = new Timer(); // Создаем таймер
final Handler uiHandler = new Handler();
myTimer.schedule(new TimerTask() { // Определяем задачу
@Override
public void run() {
uiHandler.post(new Runnable() {
@Override
public void run() {
}
});
}
;
}, 0L, 10L * 1000); // интервал - 10000 миллисекунд, 0 миллисекунд до первого запуска.
更新
我在这段代码中出错了:
Timer myTimer = new Timer();
final Handler uiHandler = new Handler();
myTimer.schedule(new TimerTask() {
@Override
public void run() {
while (songRefreshing) {
uiHandler.post(new Runnable() {
@Override
public void run() {
try {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = null;
response = httpclient.execute(new HttpGet(Const.php_url));
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
String responseString = out.toString();
if (app.getCurSong() == null || app.getCurSong().intern() != responseString.intern()) {
app.setCurSong(responseString);
song_name.setText(app.getCurSong());
Log.d(LOG_TAG, "refreshCurSung - " + responseString);
}
} else {
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (IOException e) {
e.printStackTrace();
Log.d(LOG_TAG, e.toString());
}
}
});
}
}
;
}, 0L, 10L * 1000); // 10s interval
错误:
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1178)
at java.net.InetAddress.lookupHostByName(InetAddress.java:394)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:245)
at java.net.InetAddress.getAllByName(InetAddress.java:220)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:590)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:510)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:488)
这是否意味着TimerTask不在新线程中执行?
要直接回答您的问题,请从这里引用:
课程概述
计时器安排一次性或重复执行任务。 首选ScheduledThreadPoolExecutor以获取新代码。
每个计时器都有一个线程,在该线程上顺序执行任务。 当此线程忙于运行任务时,可运行的任务可能会受到延迟。
一次射击计划在绝对时间或相对延迟之后运行。
重复任务按固定期间或固定费率安排:
使用默认的固定期间执行,相对于上一次运行的开始时间,每个连续运行的任务都会被调度,因此两次运行的时间永远不会比指定的时间段更接近。 通过固定速率执行,可以安排每次连续运行任务的开始时间,而不考虑上次运行的时间。 如果延迟阻止计时器按时启动任务,这可能会导致一系列的聚合运行(一个紧接着一个启动)。 当不再需要计时器时,用户应该调用cancel(),这会释放计时器的线程和其他资源。 未明确取消的计时器可能无限期地保留资源。
此类不提供有关任务调度的实时性质的保证。 多个线程可以共享单个计时器而无需同步。
所以是的,这是一个线程。
更新 (更新问题后):
当前的实现可能包含很多缺陷,这就是为什么我建议你将Runnable
中的代码放在AsyncTask
(并将整堆代码放在doInBackground
方法中)。 在那里你可以轻松控制它。
此外,我认为@Overriding
run()
两次在另一个内部可能导致你陷入僵局。 由于TimerTask
实际上是一个Thread,所以我不认为你需要一个单独的Runnable
。
首先删除Runnable
的实现,然后尝试使用其中的HttpClient
启动TimerTask
(没有Runnable
)。 如果你无法做到这一点,那么把代码(如建议的那样)放在AsyncTask
(无论如何你都会有一个更漂亮的实现)。
谢谢
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.